<template>
  <div class="slope-monitoring" @click="closeContextMenu">
    <!-- 三维场景加载提示 -->
    <div v-if="loadingThreeJS" class="loading-overlay">
      <div class="loading-content">
        <el-icon class="loading-icon">
          <Loading />
        </el-icon>
        <span>正在初始化三维场景...</span>
      </div>
    </div>
    <!-- 过滤监测点加载提示 -->
    <div v-if="filteringPoints" class="loading-overlay">
      <div class="loading-content">
        <el-icon class="loading-icon">
          <Loading />
        </el-icon>
        <span>正在过滤屏蔽区域内的监测点...</span>
      </div>
    </div>

    <!-- 主布局容器 -->
    <div class="main-layout">
      <!-- 顶部菜单栏 -->
      <el-header class="header">
        <el-menu :default-active="activeMenu" :default-openeds="defaultOpeneds" class="top-menu" mode="horizontal"
          background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" @select="handleMenuSelect">
          <!-- 数据管理中心 -->
          <el-sub-menu index="1" popper-append-to-body="false" popper-class="custom-popper">
            <template v-slot:title>
              <span class="menu-title">数据管理中心</span>
            </template>
            <el-menu-item index="1-1">监测数据设置</el-menu-item>
            <el-menu-item index="1-2">开启/关闭自动导入</el-menu-item>
            <el-sub-menu index="1-3">
              <template v-slot:title>
                <span>手工数据导入</span>
              </template>
              <el-menu-item index="1-3-1">GNSS数据导入</el-menu-item>
              <el-menu-item index="1-3-2">全站仪数据导入</el-menu-item>
              <el-menu-item index="1-3-3">InSAR数据导入</el-menu-item>
              <el-menu-item index="1-3-4">地下水位数据导入</el-menu-item>
              <el-menu-item index="1-3-5">降雨量数据导入</el-menu-item>
            </el-sub-menu>
            <el-menu-item index="1-4">数据质量评估</el-menu-item>
            <el-menu-item index="1-5">多源数据融合配置</el-menu-item>
            <el-menu-item index="1-6">数据导出</el-menu-item>
          </el-sub-menu>

          <!-- 数据融合分析 -->
          <el-sub-menu index="2" popper-append-to-body="false" popper-class="custom-popper">
            <template v-slot:title>
              <span class="menu-title">数据融合分析</span>
            </template>
            <el-menu-item index="2-1">形变-降雨耦合分析</el-menu-item>
            <el-menu-item index="2-2">位移-水位-降雨关联分析</el-menu-item>
            <el-menu-item index="2-3">主控因素敏感性分析</el-menu-item>
            <el-menu-item index="2-4">滑坡孕育阶段自动识别</el-menu-item>
          </el-sub-menu>

          <!-- 判据与风险指标分析 -->
          <el-sub-menu index="3" popper-append-to-body="false" popper-class="custom-popper">
            <template v-slot:title>
              <span class="menu-title">判据与风险指标分析</span>
            </template>
            <el-menu-item index="3-1">累积位移分析</el-menu-item>
            <el-menu-item index="3-2">位移速率分析</el-menu-item>
            <el-menu-item index="3-3">加速度分析</el-menu-item>
            <el-menu-item index="3-4">F-V判据自动识别图</el-menu-item>
            <el-menu-item index="3-5">自动诊断报告生成</el-menu-item>
          </el-sub-menu>

          <!-- AI风险评估与模型管理 -->
          <el-sub-menu index="4" popper-append-to-body="false" popper-class="custom-popper">
            <template v-slot:title>
              <span class="menu-title">AI风险评估与模型管理</span>
            </template>
            <el-menu-item index="4-1">数据集管理</el-menu-item>
            <el-menu-item index="4-2">AI模型训练</el-menu-item>
            <el-menu-item index="4-3">风险预测曲线</el-menu-item>
            <el-menu-item index="4-4">模型效果对比</el-menu-item>
            <el-menu-item index="4-5">预警规则</el-menu-item>
          </el-sub-menu>

          <!-- 预警信息管理 -->
          <el-sub-menu index="5" popper-append-to-body="false" popper-class="custom-popper">
            <template v-slot:title>
              <span class="menu-title">预警信息管理</span>
            </template>
            <el-menu-item index="5-1">历史预警记录</el-menu-item>
            <el-menu-item index="5-2">阈值与智能策略混合控制</el-menu-item>
            <el-menu-item index="5-3">预警可信度评分</el-menu-item>
            <el-menu-item index="5-4">预警通知</el-menu-item>
          </el-sub-menu>

          <!-- 滑坡信息管理 -->
          <el-sub-menu index="6" popper-append-to-body="false" popper-class="custom-popper">
            <template v-slot:title>
              <span class="menu-title">滑坡信息管理</span>
            </template>
            <el-menu-item index="6-1">历史滑坡信息</el-menu-item>
            <el-menu-item index="6-2">添加滑坡信息</el-menu-item>
          </el-sub-menu>

          <!-- 时空演化可视化 -->
          <el-sub-menu index="7" popper-append-to-body="false" popper-class="custom-popper">
            <template v-slot:title>
              <span class="menu-title">时空演化可视化</span>
            </template>
            <el-menu-item index="7-1">监测点显示设置</el-menu-item>
            <el-menu-item index="7-2">屏蔽区域设置</el-menu-item>
            <el-menu-item index="7-3">变形/速度/加速度时间轴动态</el-menu-item>
            <el-menu-item index="7-4">降雨/水位时间轴动态</el-menu-item>
            <el-menu-item index="7-5">滑坡孕育区热力图</el-menu-item>
          </el-sub-menu>

          <!-- 系统设置 -->
          <el-sub-menu index="8" popper-append-to-body="false" popper-class="custom-popper">
            <template v-slot:title>
              <span class="menu-title">系统设置</span>
            </template>
            <el-menu-item index="8-1">用户管理</el-menu-item>
            <el-menu-item index="8-2">权限设置</el-menu-item>
            <el-menu-item index="8-3">系统日志</el-menu-item>
          </el-sub-menu>
        </el-menu>
      </el-header>

      <!-- 内容容器 -->
      <div class="content-container">
        <!-- 左侧边栏 -->
        <el-aside :style="{ width: leftPanelWidth + 'px' }" class="sidebar">
          <div class="panel-header">
            <el-icon :class="{ 'rotate-180': !showLeftPanel }" @click="toggleLeftPanel">
              <ArrowRight />
            </el-icon>
          </div>
          <div v-show="showLeftPanel" class="sidebar-content">
            <el-tree ref="treeRef" :data="treeData" :props="treeProps" @node-click="handleNodeClick"
              @node-expand="nodeExpanded" @node-collapse="nodeCollapsed" node-key="id" :expand-on-click-node="false"
              :default-expanded-keys="defaultExpandedKeys" :current-node-key="currentNodeKey">
              <template v-slot:default="{ node, data }">
                <div class="tree-node-content" @click.stop="handleLabelClick(node, $event)"
                  @contextmenu.stop="handleNodeContextMenu(data, node, $event)">
                  <span class="node-label"
                    :class="getAlertClass(node.data.type === 'point' ? node.data.alert_level : null)"
                    @click.stop="handleLabelClick(node, $event)">
                    {{ node.label }}
                  </span>
                  <el-icon class="visibility-icon" @click.stop="toggleVisibility(data, node, $event)"
                    :class="{ 'is-hidden': !isNodeVisible(data) }">
                    <View v-if="isNodeVisible(data)" />
                    <Hide v-else />
                  </el-icon>
                </div>
              </template>
            </el-tree>
          </div>
          <!-- 左侧调整条 -->
          <div class="resizer resizer-left" @mousedown="startResizeLeft"></div>
        </el-aside>

        <!-- 主内容区域 -->
        <div class="main-content-area">
          <div ref="canvas" class="canvas-container">
            <!-- 浮动工具栏 -->
            <div class="floating-toolbar" :class="{ 'toolbar-hidden': isToolbarHidden }">
              <div class="toolbar-content">
                <el-button-group v-show="!isToolbarHidden">
                  <el-button @click="toggleFullscreen" class="toolbar-btn">
                    <el-icon>
                      <FullScreen />
                    </el-icon>
                  </el-button>
                  <el-button @click="zoomIn" class="toolbar-btn">
                    <el-icon>
                      <ZoomIn />
                    </el-icon>
                  </el-button>
                  <el-button @click="zoomOut" class="toolbar-btn">
                    <el-icon>
                      <ZoomOut />
                    </el-icon>
                  </el-button>
                  <el-button @click="resetView" class="toolbar-btn">
                    <el-icon>
                      <Refresh />
                    </el-icon>
                  </el-button>
                  <!-- 网格切换按钮 -->
                  <el-button @click="toggleGridHelper" class="toolbar-btn" :type="showGridHelper ? 'primary' : ''">
                    <svg viewBox="0 0 1024 1024" width="16" height="16">
                      <path d="M128 128h768v768H128z" fill="none" stroke="currentColor" stroke-width="64" />
                      <path d="M128 384h768M128 640h768M384 128v768M640 128v768" stroke="currentColor"
                        stroke-width="64" />
                    </svg>
                  </el-button>

                  <!-- ========== 新增：选择功能按钮 ========== -->
                  <!-- 选择模式切换按钮 -->
                  <el-button @click="toggleSelectionMode" class="toolbar-btn" :type="isSelecting ? 'primary' : ''"
                    :title="isSelecting ? '选择模式开启' : '选择模式关闭'">
                    <el-icon>
                      <Select />
                    </el-icon>
                  </el-button>

                  <!-- 清除选择按钮 -->
                  <el-button @click="clearSelection" class="toolbar-btn" :disabled="!selectedObject" title="清除选择">
                    <el-icon>
                      <Close />
                    </el-icon>
                  </el-button>

                  <!-- 定位到选中对象按钮 -->
                  <el-button @click="focusOnSelectedObject" class="toolbar-btn" :disabled="!selectedObject"
                    title="定位到选中对象">
                    <el-icon>
                      <Aim />
                    </el-icon>
                  </el-button>
                  <!-- ========== 选择功能按钮结束 ========== -->

                  <el-button @click="switchToAboveView" class="toolbar-btn">
                    <img src="/above.svg" alt="Above View" style="width: 16px; height: 16px;" />
                  </el-button>
                  <el-button @click="switchToBelowView" class="toolbar-btn">
                    <img src="/below.svg" alt="Below View" style="width: 16px; height: 16px;" />
                  </el-button>
                  <el-button @click="switchToEastNorthView" class="toolbar-btn">
                    <img src="/east-north.svg" alt="East-North View" style="width: 16px; height: 16px;" />
                  </el-button>
                  <el-button @click="switchToEastSouthView" class="toolbar-btn">
                    <img src="/east-south.svg" alt="East-South View" style="width: 16px; height: 16px;" />
                  </el-button>
                  <el-button @click="switchToWestNorthView" class="toolbar-btn">
                    <img src="/west-north.svg" alt="West-North View" style="width: 16px; height: 16px;" />
                  </el-button>
                  <el-button @click="switchToWestSouthView" class="toolbar-btn">
                    <img src="/west-south.svg" alt="West-South View" style="width: 16px; height: 16px;" />
                  </el-button>
                </el-button-group>
                <!-- 切换按钮始终显示 -->
                <el-button @click="toggleToolbar" class="toolbar-toggle-btn">
                  <el-icon>
                    <ArrowLeft v-if="!isToolbarHidden" />
                    <ArrowRight v-else />
                  </el-icon>
                </el-button>
              </div>
            </div>
          </div>
        </div>

        <!-- 右侧边栏 -->
        <el-aside :style="{ width: rightPanelWidth + 'px' }" class="sidebar right-sidebar">
          <div class="panel-header">
            <el-icon :class="{ 'rotate-180': !showRightPanel }" @click="toggleRightPanel">
              <ArrowLeft />
            </el-icon>
          </div>
          <div v-show="showRightPanel" class="sidebar-content">
            <h3>属性栏</h3>

            <!-- ========== 新增：选择状态显示 ========== -->
            <div class="selection-status" v-if="selectedObject">
              <el-tag :type="getSelectionTagType(selectedObject.type)" class="selection-tag">
                {{ getSelectionTypeText(selectedObject.type) }}
              </el-tag>
              <span class="selection-name">{{ selectedObject.name }}</span>
            </div>

            <!-- 属性表格 -->
            <el-table :data="selectedProperties" style="width: 100%;" v-if="selectedProperties.length > 0" border>
              <el-table-column prop="key" label="属性" width="120"></el-table-column>
              <el-table-column prop="value" label="值"></el-table-column>
            </el-table>
            <div v-else class="empty-properties">
              <el-icon>
                <InfoFilled />
              </el-icon>
              <span>未选择任何对象</span>
              <span class="hint-text" v-if="isSelecting">点击三维场景中的对象进行选择</span>
              <span class="hint-text" v-else>选择模式已关闭</span>
            </div>

            <!-- ========== 新增：操作按钮 ========== -->
            <div class="selection-actions" v-if="selectedObject">
              <el-button size="small" @click="focusOnSelectedObject" :disabled="!selectedObject?.object3D">
                <el-icon>
                  <Aim />
                </el-icon>
                定位
              </el-button>
              <el-button size="small" @click="clearSelection">
                <el-icon>
                  <Close />
                </el-icon>
                清除
              </el-button>

              <!-- 监测点特有操作 -->
              <el-button v-if="selectedObject.type === 'point'" size="small" @click="handlePointOperation">
                <el-icon>
                  <DataLine />
                </el-icon>
                查看数据
              </el-button>
            </div>
          </div>
          <!-- 右侧调整条 -->
          <div class="resizer resizer-right" @mousedown="startResizeRight"></div>
        </el-aside>
      </div>
    </div>

    <!-- 底部状态栏 -->
    <el-footer class="status-bar">
      <div class="status-content">
        <!-- 坐标信息 -->
        <div class="status-section">
          <span class="status-label">坐标:</span>
          <span class="status-value">{{ currentCoordinates.x.toFixed(2) }}, {{ currentCoordinates.y.toFixed(2) }}, {{
            currentCoordinates.z.toFixed(2) }}</span>
        </div>

        <!-- 比例尺 -->
        <div class="status-section">
          <span class="status-label">比例尺:</span>
          <span class="status-value">1:{{ scaleFactor.toFixed(0) }}</span>
        </div>

        <!-- 视角信息 -->
        <div class="status-section">
          <span class="status-label">视角:</span>
          <span class="status-value">{{ currentViewMode }}</span>
        </div>

        <!-- 操作提示 -->
        <div class="status-section hint-section">
          <span class="status-label">提示:</span>
          <span class="status-value">{{ currentHint }}</span>
        </div>

        <!-- 系统状态 -->
        <div class="status-section">
          <span class="status-label">状态:</span>
          <span class="status-value" :class="systemStatusClass">{{ systemStatus }}</span>
        </div>

        <!-- 帧率显示 -->
        <div class="status-section">
          <span class="status-label">FPS:</span>
          <span class="status-value">{{ fps.toFixed(1) }}</span>
        </div>
      </div>
    </el-footer>

    <!-- 右键菜单 -->
    <div class="context-menu" v-show="contextMenuVisible" :style="{
      position: 'fixed',
      left: contextMenuPos.x + 'px',
      top: contextMenuPos.y + 'px',
      zIndex: 1000
    }" @click.stop>
      <el-menu>
        <!-- 监测点菜单 -->
        <template v-if="selectedObject?.type === 'point' || (currentNodeKey && isPointNode(currentNodeKey))">
          <el-menu-item index="locate" @click="handleContextMenuCommand('locate')">
            <el-icon>
              <Location />
            </el-icon><span>定位</span>
          </el-menu-item>

          <el-menu-item index="viewData" @click="handleContextMenuCommand('viewData')">
            <el-icon>
              <DataLine />
            </el-icon><span>查看数据</span>
          </el-menu-item>

          <el-menu-item index="viewDisplacement" @click="handleContextMenuCommand('viewDisplacement')">
            <el-icon>
              <TrendCharts />
            </el-icon><span>位移曲线</span>
          </el-menu-item>

          <el-menu-item index="viewVelocity" @click="handleContextMenuCommand('viewVelocity')">
            <el-icon>
              <SortUp />
            </el-icon><span>速率曲线</span>
          </el-menu-item>

          <el-menu-item index="viewAcceleration" @click="handleContextMenuCommand('viewAcceleration')">
            <el-icon>
              <Sort />
            </el-icon><span>加速度曲线</span>
          </el-menu-item>

          <el-menu-item index="specialAttention" @click="handleContextMenuCommand('specialAttention')">
            <el-icon>
              <Star />
            </el-icon><span>特别关注</span>
          </el-menu-item>
        </template>

        <!-- 可以在这里添加其他类型的菜单 -->
      </el-menu>
    </div>
    <ManageShieldArea v-model="shieldDialogVisible" :three-scene="scene" :three-camera="camera"
      :three-renderer="renderer" :three-dom-element="getCanvasElement()" :model-center="modelCenter"
      :scale-factor="scaleFactor" @show-polygons="handleShowPolygons" ref="maskAreaSettingsRef" />
  </div>

  <!-- 数据管理中心 -->
  <MonitoringDataSettings ref="monitoringDataSettingsRef" />
  <AutoInputData ref="autoinputdataRef" />
  <GNSSImport ref="gnssImportRef" />
  <TotalStationImport ref="totalStationImportRef" />
  <InSARImport ref="insarImportRef" />
  <GroundwaterImport ref="groundwaterImportRef" />
  <RainfallImport ref="rainfallImportRef" />
  <DataQualityAssessment ref="dataQualityAssessmentRef" />
  <DataFusionConfig ref="dataFusionConfigRef" />
  <DataExport ref="dataExportRef" />

  <!-- 数据融合分析 -->
  <DeformationRainfallAnalysis ref="deformationRainfallAnalysisRef" />
  <DisplacementWaterRainfallAnalysis ref="displacementWaterRainfallAnalysisRef" />
  <SensitivityAnalysis ref="sensitivityAnalysisRef" />
  <LandslideIncubationRecognition ref="landslideIncubationRecognitionRef" />

  <!-- 判据与风险指标分析 -->
  <DisplacementAnalysis ref="displacementAnalysisRef" />
  <VelocityAnalysis ref="velocityAnalysisRef" />
  <AccelerationAnalysis ref="accelerationAnalysisRef" />
  <FVRecognitionChart ref="fVRecognitionChartRef" />
  <AutoDiagnosisReport ref="autoDiagnosisReportRef" />

  <!-- AI风险评估与模型管理 -->
  <DatasetManagement ref="datasetManagementRef" />
  <AIModelTraining ref="aIModelTrainingRef" />
  <RiskPredictionCurve ref="riskPredictionCurveRef" />
  <ModelComparison ref="modelComparisonRef" />
  <WarningRules ref="warningRulesRef" />

  <!-- 预警信息管理 -->
  <WarningRecords ref="warningRecordsRef" />
  <WarningHybridStrategy ref="warningHybridStrategyRef" />
  <WarningCredibility ref="warningCredibilityRef" />
  <WarningNotification ref="warningNotificationRef" />

  <!-- 滑坡信息管理 -->
  <HistoryLandslide ref="historyLandslideRef" />
  <AddLandslide ref="addLandslideRef" />

  <!-- 时空演化可视化 -->
  <PointDisplaySettings ref="pointDisplaySettingsRef" />
  <ManageShieldArea ref="maskAreaSettingsRef" />
  <DeformationTimeline ref="deformationTimelineRef" />
  <RainfallWaterTimeline ref="rainfallWaterTimelineRef" />
  <LandslideHeatmap ref="landslideHeatmapRef" />

  <!-- 系统设置 -->
  <UserManagement ref="userManagementRef" />
  <PermissionSettings ref="permissionSettingsRef" />
  <SystemLog ref="systemLogRef" />

  <!-- 左侧边栏按钮 -->
  <MonitoringDialog ref="monitoringDialogRef" />
  <DisplacementChart ref="displacementChartRef" />
  <VelocityChart ref="velocityChartRef" />
  <AccelerationChart ref="accelerationChartRef" />
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
import { reactive, computed } from 'vue';
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import {
  FullScreen,
  ZoomIn,
  ZoomOut,
  Refresh,
  ArrowRight,
  ArrowLeft,
  InfoFilled,
  DataLine,
  TrendCharts,
  SortUp,
  Sort,
  View,
  Hide,
  Location,
  Loading,
  // ========== 新增选择功能图标 ==========
  Select,
  Close,
  Aim
} from '@element-plus/icons-vue';
import axios from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus'

// ========== 数据管理中心 ==========
import MonitoringDataSettings from "./数据管理中心/MonitoringDataSettings.vue";
import AutoInputData from "./数据管理中心/AutoInputData.vue";
import GNSSImport from "./数据管理中心/GNSSImport.vue";
import TotalStationImport from "./数据管理中心/TotalStationImport.vue";
import InSARImport from "./数据管理中心/InSARImport.vue";
import GroundwaterImport from "./数据管理中心/GroundwaterImport.vue";
import RainfallImport from "./数据管理中心/RainfallImport.vue";
import DataQualityAssessment from "./数据管理中心/DataQualityAssessment.vue";
import DataFusionConfig from "./数据管理中心/DataFusionConfig.vue";
import DataExport from "./数据管理中心/DataExport.vue";

// ========== 数据融合分析 ==========
import DeformationRainfallAnalysis from "./数据融合分析/DeformationRainfallAnalysis.vue";
import DisplacementWaterRainfallAnalysis from "./数据融合分析/DisplacementWaterRainfallAnalysis.vue";
import SensitivityAnalysis from "./数据融合分析/SensitivityAnalysis.vue";
import LandslideIncubationRecognition from "./数据融合分析/LandslideIncubationRecognition.vue";

// ========== 判据与风险指标分析 ==========
import DisplacementAnalysis from "./判据与风险指标分析/DisplacementAnalysis.vue";
import VelocityAnalysis from "./判据与风险指标分析/VelocityAnalysis.vue";
import AccelerationAnalysis from "./判据与风险指标分析/AccelerationAnalysis.vue";
import FVRecognitionChart from "./判据与风险指标分析/FVRecognitionChart.vue";
import AutoDiagnosisReport from "./判据与风险指标分析/AutoDiagnosisReport.vue";

// ========== AI风险评估与模型管理 ==========
import DatasetManagement from "./AI风险评估与模型管理/DatasetManagement.vue";
import AIModelTraining from "./AI风险评估与模型管理/AIModelTraining.vue";
import RiskPredictionCurve from "./AI风险评估与模型管理/RiskPredictionCurve.vue";
import ModelComparison from "./AI风险评估与模型管理/ModelComparison.vue";
import WarningRules from "./AI风险评估与模型管理/WarningRules.vue";

// ========== 预警信息管理 ==========
import WarningRecords from "./预警信息管理/WarningRecords.vue";
import WarningHybridStrategy from "./预警信息管理/WarningHybridStrategy.vue";
import WarningCredibility from "./预警信息管理/WarningCredibility.vue";
import WarningNotification from "./预警信息管理/WarningNotification.vue";

// ========== 滑坡信息管理 ==========
import HistoryLandslide from "./滑坡信息管理/HistoryLandslide.vue";
import AddLandslide from "./滑坡信息管理/AddLandslide.vue";

// ========== 时空演化可视化 ==========
import PointDisplaySettings from "./时空演化可视化/PointDisplaySettings.vue";
import ManageShieldArea from "./时空演化可视化/ManageShieldarea.vue";
import DeformationTimeline from "./时空演化可视化/DeformationTimeline.vue";
import RainfallWaterTimeline from "./时空演化可视化/RainfallWaterTimeline.vue";
import LandslideHeatmap from "./时空演化可视化/LandslideHeatmap.vue";

// ========== 系统设置 ==========
import UserManagement from "./系统设置/UserManagement.vue";
import PermissionSettings from "./系统设置/PermissionSettings.vue";
import SystemLog from "./系统设置/SystemLog.vue";

// ========== 左菜单栏操作 ==========
import MonitoringDialog from "./左菜单栏操作/MonitoringDialog.vue";
import DisplacementChart from "./左菜单栏操作/DisplacementChart.vue";
import VelocityChart from './左菜单栏操作/VelocityChart.vue';
import AccelerationChart from './左菜单栏操作/AccelerationChart.vue';

// ========== 导入选择管理器 ==========
import { SelectionManager, type SelectableObject } from './utils/SelectionManager';
// ========== 选择功能相关 ==========
const selectedObject = ref<SelectableObject | null>(null);
const isSelecting = ref<boolean>(true);


// ========== 页面控制集合 ==========
// 数据管理中心
const monitoringDataSettingsRef = ref<InstanceType<typeof MonitoringDataSettings> | null>(null);
const autoinputdataRef = ref<InstanceType<typeof AutoInputData> | null>(null);
const gnssImportRef = ref<InstanceType<typeof GNSSImport> | null>(null);
const totalStationImportRef = ref<InstanceType<typeof TotalStationImport> | null>(null);
const insarImportRef = ref<InstanceType<typeof InSARImport> | null>(null);
const groundwaterImportRef = ref<InstanceType<typeof GroundwaterImport> | null>(null);
const rainfallImportRef = ref<InstanceType<typeof RainfallImport> | null>(null);
const dataQualityAssessmentRef = ref<InstanceType<typeof DataQualityAssessment> | null>(null);
const dataFusionConfigRef = ref<InstanceType<typeof DataFusionConfig> | null>(null);
const dataExportRef = ref<InstanceType<typeof DataExport> | null>(null);

// 数据融合分析
const deformationRainfallAnalysisRef = ref<InstanceType<typeof DeformationRainfallAnalysis> | null>(null);
const displacementWaterRainfallAnalysisRef = ref<InstanceType<typeof DisplacementWaterRainfallAnalysis> | null>(null);
const sensitivityAnalysisRef = ref<InstanceType<typeof SensitivityAnalysis> | null>(null);
const landslideIncubationRecognitionRef = ref<InstanceType<typeof LandslideIncubationRecognition> | null>(null);

// 判据与风险指标分析
const displacementAnalysisRef = ref<InstanceType<typeof DisplacementAnalysis> | null>(null);
const velocityAnalysisRef = ref<InstanceType<typeof VelocityAnalysis> | null>(null);
const accelerationAnalysisRef = ref<InstanceType<typeof AccelerationAnalysis> | null>(null);
const fVRecognitionChartRef = ref<InstanceType<typeof FVRecognitionChart> | null>(null);
const autoDiagnosisReportRef = ref<InstanceType<typeof AutoDiagnosisReport> | null>(null);

// AI风险评估与模型管理
const datasetManagementRef = ref<InstanceType<typeof DatasetManagement> | null>(null);
const aIModelTrainingRef = ref<InstanceType<typeof AIModelTraining> | null>(null);
const riskPredictionCurveRef = ref<InstanceType<typeof RiskPredictionCurve> | null>(null);
const modelComparisonRef = ref<InstanceType<typeof ModelComparison> | null>(null);
const warningRulesRef = ref<InstanceType<typeof WarningRules> | null>(null);

// 预警信息管理
const warningRecordsRef = ref<InstanceType<typeof WarningRecords> | null>(null);
const warningHybridStrategyRef = ref<InstanceType<typeof WarningHybridStrategy> | null>(null);
const warningCredibilityRef = ref<InstanceType<typeof WarningCredibility> | null>(null);
const warningNotificationRef = ref<InstanceType<typeof WarningNotification> | null>(null);

// 滑坡信息管理
const historyLandslideRef = ref<InstanceType<typeof HistoryLandslide> | null>(null);
const addLandslideRef = ref<InstanceType<typeof AddLandslide> | null>(null);

// 时空演化可视化
const pointDisplaySettingsRef = ref<InstanceType<typeof PointDisplaySettings> | null>(null);
const maskAreaSettingsRef = ref<InstanceType<typeof ManageShieldArea> | null>(null);
const deformationTimelineRef = ref<InstanceType<typeof DeformationTimeline> | null>(null);
const rainfallWaterTimelineRef = ref<InstanceType<typeof RainfallWaterTimeline> | null>(null);
const landslideHeatmapRef = ref<InstanceType<typeof LandslideHeatmap> | null>(null);

// 系统设置
const userManagementRef = ref<InstanceType<typeof UserManagement> | null>(null);
const permissionSettingsRef = ref<InstanceType<typeof PermissionSettings> | null>(null);
const systemLogRef = ref<InstanceType<typeof SystemLog> | null>(null);

// 左侧边栏图表组件
const monitoringDialogRef = ref<InstanceType<typeof MonitoringDialog> | null>(null);
const displacementChartRef = ref<InstanceType<typeof DisplacementChart> | null>(null);
const velocityChartRef = ref<InstanceType<typeof VelocityChart> | null>(null);
const accelerationChartRef = ref<InstanceType<typeof AccelerationChart> | null>(null);

// ========== 屏蔽区域相关 ==========
const shieldDialogVisible = ref(false);

// 添加屏蔽区域数据
const shieldAreas = ref<any[]>([]);
// 添加加载状态
const filteringPoints = ref(false);

// Define types
interface TreeNode {
  id: string;
  label: string;
  type?: 'point' | 'model' | 'category';
  alert_level?: 'ERROR' | 'WARNING' | 'ATTENTION' | null;
  x?: number;
  y?: number;
  z?: number;
  point_id?: number;
  children?: TreeNode[];
}

interface MonitoringPoint {
  point_id: number;
  point_name: string;
  point_type: string;
  alert_level: 'ERROR' | 'WARNING' | 'ATTENTION' | null;
  x: number;
  y: number;
  z: number;
}

interface Property {
  key: string;
  value: string;
}

interface ContextMenuPosition {
  x: number;
  y: number;
}

// Reactive data
const treeData = ref<TreeNode[]>([]);
const treeProps = {
  children: 'children',
  label: 'label',
  id: 'id',
} as const;
const currentNodeKey = ref<string | undefined>(undefined);
const canvas = ref<HTMLDivElement | null>(null);
const treeRef = ref<InstanceType<typeof import('element-plus').ElTree> | null>(null);
const monitoringPoints = ref<MonitoringPoint[]>([]);
const selectedProperties = ref<Property[]>([]);
const showLeftPanel = ref<boolean>(localStorage.getItem('leftPanelState') !== 'false');
const showRightPanel = ref<boolean>(localStorage.getItem('rightPanelState') !== 'false');
const isFullscreen = ref<boolean>(false);
const contextMenuVisible = ref<boolean>(false);
const contextMenuPos = ref<ContextMenuPosition>({ x: 0, y: 0 });
const visibility = ref<Record<string, boolean>>({});
const defaultExpandedKeys = ref<string[]>([]);
const highlightedPoint = ref<string | null>(null);
const activeMenu = ref<string>('1');
const defaultOpeneds = ref<string[]>([]);
const needsRender = ref<boolean>(true);
const isToolbarHidden = ref<boolean>(false);

// Three.js 初始化状态
const threeInitialized = ref(false)
const loadingThreeJS = ref(false)
const initializationPromise = ref<Promise<void> | null>(null)

// Dynamic widths
const leftPanelWidth = ref<number>(parseInt(localStorage.getItem('leftPanelWidth') ?? '200'));
const rightPanelWidth = ref<number>(parseInt(localStorage.getItem('rightPanelWidth') ?? '300'));
const minPanelWidth = 40;
const maxPanelWidth = 500;

// Three.js related variables
let scene: THREE.Scene | null = null;
let camera: THREE.PerspectiveCamera | null = null;
let renderer: THREE.WebGLRenderer | null = null;
let controls: OrbitControls | null = null;
let model: THREE.Group | null = null;
const modelCenter = ref<THREE.Vector3>(new THREE.Vector3());
let axesGroup: THREE.Group | null = null;
let axesScene: THREE.Scene;
let axesCamera: THREE.OrthographicCamera;
let scaleFactor: number = 1;

// Drag state
let isResizingLeft: boolean = false;
let isResizingRight: boolean = false;

// Geometry for monitoring points
const sphereGeometry = new THREE.SphereGeometry(5, 16, 16);

// 坐标偏移常量
const COORDINATE_OFFSET = {
  x: 2372256.14,
  y: 773022,
  z: 0
}

// 添加工具栏显示/隐藏功能
const toggleToolbar = (): void => {
  isToolbarHidden.value = !isToolbarHidden.value;
};

//////////////////////////////////网格助手/////////////////////////////////////
const showGridHelper = ref<boolean>(true);
let gridHelper: THREE.GridHelper | null = null;

// 创建网格助手
const createGridHelper = (): void => {
  if (!scene) return;

  if (gridHelper) {
    scene.remove(gridHelper);
    gridHelper = null;
  }

  gridHelper = new THREE.GridHelper(10000, 100, 0x444444, 0x888888);
  gridHelper.name = 'GridHelper';
  gridHelper.rotation.x = Math.PI / 2;
  gridHelper.position.set(0, 0, 0);
  scene.add(gridHelper);

  console.log('网格助手已创建');
};

// 切换网格显示/隐藏
const toggleGridHelper = (): void => {
  showGridHelper.value = !showGridHelper.value;

  if (gridHelper) {
    gridHelper.visible = showGridHelper.value;
  }

  needsRender.value = true;
  updateHint(showGridHelper.value ? '网格已显示' : '网格已隐藏')
};

// Create text label sprite
const createLabelSprite = (text: string, color: string): THREE.Sprite => {
  const canvas = document.createElement('canvas');
  const context = canvas.getContext('2d');
  const fontSize = 32;
  context!.font = `${fontSize}px Arial`;
  const textWidth = context!.measureText(text).width;
  canvas.width = textWidth + 20;
  canvas.height = fontSize + 10;

  context!.font = `${fontSize}px Arial`;
  context!.fillStyle = color;
  context!.fillText(text, 10, fontSize);

  const texture = new THREE.CanvasTexture(canvas);
  const spriteMaterial = new THREE.SpriteMaterial({ map: texture, transparent: true });
  const sprite = new THREE.Sprite(spriteMaterial);
  sprite.scale.set(canvas.width * 0.1, canvas.height * 0.1, 1);
  return sprite;
};

// 创建坐标轴标签精灵
const createAxisLabelSprite = (text: string, color: string): THREE.Sprite => {
  const canvas = document.createElement('canvas');
  const context = canvas.getContext('2d');
  if (!context) {
    console.error(`无法为坐标轴标签 "${text}" 创建 2D 上下文`);
    return new THREE.Sprite();
  }
  const fontSize = 5;
  const padding = 4;
  context.font = `${fontSize}px Arial`;
  const textWidth = context.measureText(text).width;
  canvas.width = textWidth + padding * 2;
  canvas.height = fontSize + padding * 2;

  const scale = Math.max(window.devicePixelRatio, 2);
  canvas.width *= scale;
  canvas.height *= scale;
  context.scale(scale, scale);
  context.font = `${fontSize}px Arial`;
  context.textBaseline = 'middle';
  context.fillStyle = color;
  context.fillText(text, padding, fontSize / 2 + padding);

  const texture = new THREE.CanvasTexture(canvas);
  texture.minFilter = THREE.LinearFilter;
  texture.magFilter = THREE.LinearFilter;
  const spriteMaterial = new THREE.SpriteMaterial({ map: texture, transparent: true });
  const sprite = new THREE.Sprite(spriteMaterial);
  sprite.scale.set(canvas.width * 0.05 / scale, canvas.height * 0.05 / scale, 1);
  return sprite;
};

// 创建屏幕固定坐标轴
const createScreenFixedAxes = (): THREE.Group => {
  const group = new THREE.Group();
  group.name = 'Screen_Fixed_Axes';

  const axisLength = 0.5;
  const axisRadius = 0.02;
  const arrowLength = 0.15;
  const arrowRadius = 0.05;
  const labelOffset = 0.2;

  try {
    // X轴（红色）
    const xAxis = new THREE.Mesh(
      new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, 8),
      new THREE.MeshBasicMaterial({ color: 0xff0000 })
    );
    xAxis.rotation.z = -Math.PI / 2;
    xAxis.position.set(axisLength / 2, 0, 0);
    group.add(xAxis);

    const xArrow = new THREE.Mesh(
      new THREE.ConeGeometry(arrowRadius, arrowLength, 8),
      new THREE.MeshBasicMaterial({ color: 0xff0000 })
    );
    xArrow.rotation.z = -Math.PI / 2;
    xArrow.position.set(axisLength, 0, 0);
    group.add(xArrow);

    const xLabel = createAxisLabelSprite('X', '#ff0000');
    xLabel.position.set(axisLength + arrowLength + labelOffset, 0, 0);
    xLabel.name = 'label_X';
    group.add(xLabel);

    // Y轴（绿色）
    const yAxis = new THREE.Mesh(
      new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, 8),
      new THREE.MeshBasicMaterial({ color: 0x00ff00 })
    );
    yAxis.position.set(0, axisLength / 2, 0);
    group.add(yAxis);

    const yArrow = new THREE.Mesh(
      new THREE.ConeGeometry(arrowRadius, arrowLength, 8),
      new THREE.MeshBasicMaterial({ color: 0x00ff00 })
    );
    yArrow.position.set(0, axisLength, 0);
    group.add(yArrow);

    const yLabel = createAxisLabelSprite('Y', '#00ff00');
    yLabel.position.set(0, axisLength + arrowLength + labelOffset, 0);
    yLabel.name = 'label_Y';
    group.add(yLabel);

    // Z轴（蓝色）
    const zAxis = new THREE.Mesh(
      new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, 8),
      new THREE.MeshBasicMaterial({ color: 0x0000ff })
    );
    zAxis.rotation.x = Math.PI / 2;
    zAxis.position.set(0, 0, axisLength / 2);
    group.add(zAxis);

    const zArrow = new THREE.Mesh(
      new THREE.ConeGeometry(arrowRadius, arrowLength, 8),
      new THREE.MeshBasicMaterial({ color: 0x0000ff })
    );
    zArrow.rotation.x = Math.PI / 2;
    zArrow.position.set(0, 0, axisLength);
    group.add(zArrow);

    const zLabel = createAxisLabelSprite('Z', '#0000ff');
    zLabel.position.set(0, 0, axisLength + arrowLength + labelOffset);
    zLabel.name = 'label_Z';
    group.add(zLabel);

    console.log('Rhino 风格坐标轴创建完成，包含对象数:', group.children.length);
    return group;
  } catch (error) {
    console.error('创建坐标轴失败:', error);
    return new THREE.Group();
  }
};

// 初始化 HUD 坐标轴场景
const initAxesScene = () => {
  axesScene = new THREE.Scene();
  axesScene.background = null;
  axesCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 10);
  axesCamera.position.set(0, 0, 2);
  axesCamera.lookAt(0, 0, 0);

  axesGroup = createScreenFixedAxes();
  if (axesGroup) {
    axesScene.add(axesGroup);
    console.log('坐标轴已添加到 HUD 场景:', axesGroup.name, '子对象:', axesGroup.children.length);
  } else {
    console.error('无法添加坐标轴到 HUD 场景');
  }
};

// 修改 Initialize Three.js scene 为 Promise
const initThree = (): Promise<void> => {
  return new Promise((resolve, reject) => {
    nextTick(() => {
      if (!canvas.value) {
        const error = 'Canvas container 未找到'
        console.error(error)
        reject(new Error(error))
        return
      }

      console.log('Canvas 容器:', canvas.value)

      try {
        // 创建 canvas 元素
        const canvasElement = document.createElement('canvas')
        canvas.value.appendChild(canvasElement)

        scene = new THREE.Scene()
        scene.background = new THREE.Color(0x000000)

        // 增加 far 平面到 100000
        camera = new THREE.PerspectiveCamera(75, window.innerWidth / (window.innerHeight - 60), 0.1, 100000)
        camera.position.set(0, 0, 5000)

        renderer = new THREE.WebGLRenderer({
          antialias: true,
          canvas: canvasElement,
          alpha: true
        })

        const width = canvas.value.clientWidth
        const height = canvas.value.clientHeight
        renderer.setSize(width, height)
        renderer.shadowMap.enabled = true
        renderer.shadowMap.type = THREE.PCFSoftShadowMap
        renderer.autoClear = false
        console.log('Renderer 已创建，尺寸:', width, 'x', height)

        // 检查 WebGL 上下文
        if (!renderer.getContext()) {
          const error = 'WebGL 上下文创建失败'
          console.error(error)
          reject(new Error(error))
          return
        }

        setupLights()

        // 创建网格助手
        createGridHelper()

        // 初始化 HUD 坐标轴
        initAxesScene()

        controls = new OrbitControls(camera, renderer.domElement)
        controls.enableDamping = true
        controls.target.set(0, 0, 0)

        // 关键：把 controls 挂到 scene 上，供 PolygonDrawer3D 使用
        scene.userData.controls = controls   // 加上这行！！！

        controls.addEventListener('change', () => {
          needsRender.value = true
        })

        // 加载三维模型
        loadModel().then(() => {
          threeInitialized.value = true
          console.log('Three.js 初始化完成')

          // ========== 新增：初始化选择管理器 ==========
          initSelectionManager()
          console.log('选择管理器初始化完成')

          // 初始化画布右键菜单
          initCanvasContextMenu();
          console.log('画布右键菜单初始化完成');

          // ========== 新增：加载完成后切换到俯视图 ==========
          nextTick(() => {
            setTimeout(() => {
              if (camera && controls && model) {
                switchToAboveView()
                console.log('初始视图已切换到俯视图')
              }
            }, 100)
          })

          resolve()
        }).catch(reject)

        // 获取并显示监测点
        //fetchMonitoringPoints()
        animate()

      } catch (error) {
        console.error('Three.js 初始化失败:', error)
        reject(error)
      }
    })
  })
}

// 创建选择管理器实例
const selectionManager = new SelectionManager(
  selectedObject,
  selectedProperties, // 使用已有的 selectedProperties
  isSelecting,
  monitoringPoints,
  shieldAreas
);

// 获取当前选中的监测点名称
const getCurrentPointName = (): string | null => {
  // 优先级1：画布选中的监测点
  if (selectedObject.value && selectedObject.value.type === 'point') {
    return selectedObject.value.name;
  }
  
  // 优先级2：树节点选中的监测点
  if (currentNodeKey.value) {
    const node = treeRef.value?.getNode(currentNodeKey.value);
    if (node && node.data.type === 'point') {
      return node.label;
    }
  }
  
  return null;
};

// 获取当前选中的监测点ID
const getCurrentPointId = (): number | null => {
  // 优先级1：画布选中的监测点
  if (selectedObject.value && selectedObject.value.type === 'point') {
    const pointId = selectionManager.getSelectedPointId();
    if (pointId) return pointId;
  }
  
  // 优先级2：树节点选中的监测点
  if (currentNodeKey.value) {
    const node = treeRef.value?.getNode(currentNodeKey.value);
    if (node && node.data.type === 'point' && node.data.point_id) {
      return node.data.point_id;
    }
  }
  
  return null;
};

// 初始化选择管理器时添加右键菜单支持
const initSelectionManager = (): void => {
  if (!scene || !camera || !controls || !renderer) {
    console.warn('Three.js 环境未就绪，无法初始化选择管理器');
    return;
  }

  selectionManager.initialize(
    scene,
    camera,
    controls,
    renderer,
    model,
    modelCenter.value,
    scaleFactor
  );

  // 添加右键菜单回调
  selectionManager.onContextMenu = handleCanvasContextMenu;

  console.log('选择管理器初始化成功');
};

// 处理画布右键菜单
const handleCanvasContextMenu = (event: MouseEvent, object: SelectableObject | null): void => {
  console.log('画布右键菜单:', event, object);

  if (event && event.clientX && event.clientY) {
    contextMenuPos.value = { x: event.clientX, y: event.clientY };

    if (object) {
      // 根据对象类型显示菜单
      showContextMenuForSelectedObject();
    } else {
      contextMenuVisible.value = false;
    }
  }
};

// 修改画布右键事件监听
const initCanvasContextMenu = (): void => {
  const canvasElement = getCanvasElement();
  if (canvasElement) {
    canvasElement.addEventListener('contextmenu', (event) => {
      // 阻止默认的右键菜单
      event.preventDefault();
      event.stopPropagation();
      
      console.log('画布右键点击事件触发');
      
      // 如果有选中的对象，显示对应的菜单
      if (selectedObject.value) {
        console.log('有选中对象，显示右键菜单:', selectedObject.value);
        contextMenuPos.value = { x: event.clientX, y: event.clientY };
        showContextMenuForSelectedObject();
      } else {
        console.log('没有选中对象，不显示菜单');
        contextMenuVisible.value = false;
      }
    });
  }
};
// 简化的选择操作函数
const clearSelection = (): void => {
  selectionManager.clearSelection();
  updateHint('已清除选择');
};

const toggleSelectionMode = (): void => {
  selectionManager.toggleSelectionMode();
  updateHint(selectionManager.isSelecting.value ? '选择模式: 开启' : '选择模式: 关闭');
};

// 统一的定位函数
const focusOnSelectedObject = (): void => {
  // 优先级1：如果有点击选中的对象
  if (selectedObject.value) {
    selectionManager.focusOnSelectedObject();
    if (selectedObject.value) {
      updateHint(`已定位到: ${selectedObject.value.name}`);
    }
    return;
  }

  // 优先级2：如果有右键菜单选择的节点
  if (currentNodeKey.value) {
    const node = treeRef.value?.getNode(currentNodeKey.value);
    if (node && node.data.type === 'point') {
      locateNodePoint(node);
    } else if (node && node.data.type === 'model') {
      // 如果是模型，定位到模型中心
      resetView();
      updateHint('已定位到模型中心');
    } else {
      ElMessage.warning('该类型对象不支持定位');
    }
    return;
  }

  ElMessage.warning('请先选择要定位的对象');
};

// 检查节点是否为监测点
const isPointNode = (nodeKey: string): boolean => {
  const node = treeRef.value?.getNode(nodeKey);
  return node?.data?.type === 'point';
};

// 定位树节点对应的监测点 - 修复高亮问题
const locateNodePoint = (node: any): void => {
  const pointName = node.label;
  console.log('Locating point from node:', pointName);

  const success = selectionManager.focusOnPoint(pointName);

  if (success) {
    // 高亮点 - 确保调用正确的高亮函数
    highlightPointFromName(pointName);
    updateHint(`已定位到: ${pointName}`);

    // 同时更新选中状态，确保属性面板显示正确
    const point = monitoringPoints.value.find((p) => p.point_name === pointName);
    if (point) {
      selectedObject.value = {
        id: `point_${pointName}`,
        type: 'point',
        name: pointName,
        properties: [
          { key: '名称', value: pointName },
          { key: '类型', value: '监测点' },
          { key: 'X坐标', value: point.x?.toString() || 'N/A' },
          { key: 'Y坐标', value: point.y?.toString() || 'N/A' },
          { key: 'Z坐标', value: point.z?.toString() || 'N/A' },
          { key: '告警级别', value: point.alert_level || 'N/A' },
          { key: '点ID', value: point.point_id?.toString() || 'N/A' }
        ]
      };
      selectedProperties.value = selectedObject.value.properties;

      // 触发选择管理器的高亮
      triggerSelectionHighlight(pointName);
    }
  } else {
    ElMessage.error(`定位失败: 监测点 ${pointName} 未找到`);
  }
};

// 通过名称高亮点的辅助函数
const highlightPointFromName = (pointName: string): void => {
  const mesh = scene?.getObjectByName(`point_${pointName}`) as THREE.Mesh | undefined;
  if (mesh) {
    const point = monitoringPoints.value.find((p) => p.point_name === pointName);
    const originalMaterial = getAlertMaterial(point?.alert_level ?? null);

    // 保存原始材质
    mesh.userData.originalMaterial = originalMaterial;

    // 应用高亮材质
    const highlightMaterial = new THREE.MeshBasicMaterial({
      color: 0xffff00, // 黄色高亮
    });
    mesh.material = highlightMaterial;

    // 更新标签
    const label = scene?.getObjectByName(`label_${pointName}`);
    if (label) {
      const highlightSprite = createLabelSprite(pointName, '#ffff00');
      highlightSprite.position.copy(label.position);
      highlightSprite.visible = label.visible;
      highlightSprite.name = label.name;
      scene?.remove(label);
      scene?.add(highlightSprite);
    }

    highlightedPoint.value = pointName;
  }
};

// 触发选择管理器的高亮
const triggerSelectionHighlight = (pointName: string): void => {
  const pointObject = scene?.getObjectByName(`point_${pointName}`);
  if (pointObject) {
    // 清除之前的高亮
    selectionManager.clearSelectionHighlight();

    // 应用新的高亮
    if (pointObject instanceof THREE.Mesh) {
      pointObject.userData.originalMaterial = pointObject.material;
      const highlightMaterial = new THREE.MeshBasicMaterial({
        color: 0x00ff00, // 绿色高亮，与选择管理器一致
        transparent: true,
        opacity: 0.8
      });
      pointObject.material = highlightMaterial;
    }
  }
};

const handlePointOperation = (): void => {
  const pointId = selectionManager.getSelectedPointId();
  if (pointId) {
    monitoringDialogRef.value?.open(pointId);
  }
};
// 添加辅助函数到组件作用域
const getSelectionTagType = (type: string): string => {
  return selectionManager.getSelectionTagType(type);
};

const getSelectionTypeText = (type: string): string => {
  return selectionManager.getSelectionTypeText(type);
};

const setupLights = (): void => {
  if (!scene) return;

  const sunLight = new THREE.DirectionalLight(0xffffff, 1);
  sunLight.position.set(100, 100, 5000);
  scene.add(sunLight);

  const ambientLight = new THREE.AmbientLight(0x404040, 0.5);
  scene.add(ambientLight);

  const hemiLight = new THREE.HemisphereLight(0x87ceeb, 0x8b4513, 0.3);
  hemiLight.position.set(0, 5000, 0);
  scene.add(hemiLight);
};

// 修改 loadModel 为 Promise
const loadModel = (): Promise<void> => {
  return new Promise((resolve, reject) => {
    if (!scene) {
      reject(new Error('Scene is not initialized'))
      return
    }

    if (model) scene.remove(model)

    const loader = new GLTFLoader()
    loader.load(
      '/output0.glb',
      (gltf) => {
        model = gltf.scene as THREE.Group
        model.name = 'output0'

        model.traverse((child: THREE.Object3D) => {
          if ((child as THREE.Mesh).isMesh) {
            const mesh = child as THREE.Mesh
            mesh.castShadow = true
            mesh.receiveShadow = true
          }
        })

        const box = new THREE.Box3().setFromObject(model)
        const size = box.getSize(new THREE.Vector3())
        modelCenter.value = box.getCenter(new THREE.Vector3())
        console.log('Model loaded, center:', modelCenter.value)

        scaleFactor = 1
        if (size.length() < 1) {
          scaleFactor = 100 / size.length()
          model.scale.set(scaleFactor, scaleFactor, scaleFactor)
        }

        adjustCameraPosition(box, size)

        if (scene) {
          scene.add(model)
        }

        // 调整网格位置与模型中心对齐
        if (gridHelper) {
          gridHelper.position.x = modelCenter.value.x
          gridHelper.position.y = modelCenter.value.y
        }

        updateTreeData()
        resolve()
      },
      (progress) => {
        console.log('加载进度:', (progress.loaded / progress.total * 100).toFixed(2) + '%')
      },
      (error) => {
        console.error('模型加载失败:', error)
        reject(error)
      }
    )
  })
}

const adjustCameraPosition = (box: THREE.Box3, size: THREE.Vector3): void => {
  if (!camera || !controls) return;

  const maxDim = Math.max(size.x, size.y, size.z);
  const fov = camera.fov * (Math.PI / 180);
  const cameraZ = maxDim / (2 * Math.tan(fov / 2));

  camera.position.set(0, 0, cameraZ * 1.5 * scaleFactor);
  controls.target.set(modelCenter.value.x, modelCenter.value.y, modelCenter.value.z);
};

const addMonitoringPoints = (): void => {
  if (!scene) {
    console.warn('场景未初始化，无法添加监测点');
    return;
  }

  console.log('开始管理监测点...');

  // 创建监测点组来管理所有监测点
  let monitoringPointsGroup = scene.getObjectByName('monitoring_points_group') as THREE.Group;

  if (!monitoringPointsGroup) {
    // 如果没有组，创建一个新的
    monitoringPointsGroup = new THREE.Group();
    monitoringPointsGroup.name = 'monitoring_points_group';
    scene.add(monitoringPointsGroup);
    console.log('创建新的监测点组');
  } else {
    // 如果有组，清空现有内容
    while (monitoringPointsGroup.children.length > 0) {
      const child = monitoringPointsGroup.children[0];
      monitoringPointsGroup.remove(child);

      // 清理资源
      if (child instanceof THREE.Mesh) {
        child.geometry.dispose();
        if (Array.isArray(child.material)) {
          child.material.forEach(material => material.dispose());
        } else {
          child.material.dispose();
        }
      }
    }
    console.log('清空现有监测点组');
  }

  // 添加新的监测点
  monitoringPoints.value.forEach((point, index) => {
    try {
      const material = getAlertMaterial(point.alert_level);
      const mesh = new THREE.Mesh(sphereGeometry, material);

      const adjustedX = (point.x - COORDINATE_OFFSET.x) * scaleFactor;
      const adjustedY = (point.y - COORDINATE_OFFSET.y) * scaleFactor;
      const adjustedZ = point.z * scaleFactor;

      mesh.position.set(adjustedX, adjustedY, adjustedZ);
      mesh.name = `point_${point.point_name}`;  // 确保命名正确
      mesh.castShadow = true;
      mesh.receiveShadow = true;
      
      // 设置可见性 - 使用保存的可见性状态
      const isVisible = visibility.value[point.point_name] ?? true;
      mesh.visible = isVisible;

      const color = getAlertColor(point.alert_level);
      const labelSprite = createLabelSprite(point.point_name, color);
      labelSprite.name = `label_${point.point_name}`;  // 确保命名正确
      labelSprite.position.set(adjustedX, adjustedY + 10, adjustedZ);
      labelSprite.visible = isVisible;  // 与小球同步可见性

      // 添加到组中
      monitoringPointsGroup.add(mesh);
      monitoringPointsGroup.add(labelSprite);

      // 只打印前几个点的信息，避免日志过多
      if (index < 3) {
        console.log(`添加监测点 ${point.point_name}:`, { 
          x: adjustedX, y: adjustedY, z: adjustedZ,
          meshVisible: mesh.visible,
          labelVisible: labelSprite.visible
        });
      }
    } catch (error) {
      console.error(`添加监测点 ${point.point_name} 时出错:`, error);
    }
  });

  console.log(`成功添加 ${monitoringPoints.value.length} 个监测点到组中`);
};

const getAlertMaterial = (alertLevel: 'ERROR' | 'WARNING' | 'ATTENTION' | null): THREE.MeshBasicMaterial => {
  switch (alertLevel) {
    case 'ERROR':
      return new THREE.MeshBasicMaterial({ color: 0xff0000 });
    case 'WARNING':
      return new THREE.MeshBasicMaterial({ color: 0xffa500 });
    case 'ATTENTION':
      return new THREE.MeshBasicMaterial({ color: 0xffff00 });
    default:
      return new THREE.MeshBasicMaterial({ color: 0x00ff00 });
  }
};

const getAlertColor = (alertLevel: 'ERROR' | 'WARNING' | 'ATTENTION' | null): string => {
  switch (alertLevel) {
    case 'ERROR':
      return '#ff0000';
    case 'WARNING':
      return '#ffa500';
    case 'ATTENTION':
      return '#ffff00';
    default:
      return '#00ff00';
  }
};

const highlightPoint = (pointName: string): void => {
  if (highlightedPoint.value) {
    const prevMesh = scene?.getObjectByName(highlightedPoint.value) as THREE.Mesh | undefined;
    if (prevMesh) {
      const point = monitoringPoints.value.find((p) => p.point_name === highlightedPoint.value);
      const originalMaterial = getAlertMaterial(point?.alert_level ?? null);
      prevMesh.material = originalMaterial;
    }
    const prevLabel = scene?.getObjectByName(`label_${highlightedPoint.value}`);
    if (prevLabel) {
      const point = monitoringPoints.value.find((p) => p.point_name === highlightedPoint.value);
      const originalColor = getAlertColor(point?.alert_level ?? null);
      const newSprite = createLabelSprite(highlightedPoint.value, originalColor);
      newSprite.position.copy(prevLabel.position);
      newSprite.visible = prevLabel.visible;
      newSprite.name = prevLabel.name;
      scene?.remove(prevLabel);
      scene?.add(newSprite);
    }
  }

  const mesh = scene?.getObjectByName(pointName) as THREE.Mesh | undefined;
  if (mesh) {
    const highlightMaterial = new THREE.MeshBasicMaterial({
      color: 0xffff00,
    });
    mesh.material = highlightMaterial;
    highlightedPoint.value = pointName;

    const label = scene?.getObjectByName(`label_${pointName}`);
    if (label) {
      const highlightSprite = createLabelSprite(pointName, '#ffff00');
      highlightSprite.position.copy(label.position);
      highlightSprite.visible = label.visible;
      highlightSprite.name = label.name;
      scene?.remove(label);
      scene?.add(highlightSprite);
    }
  } else {
    console.warn(`Mesh for point ${pointName} not found`);
  }
};

// 动画循环
const animate = (): void => {
  try {
    requestAnimationFrame(animate)

    if (controls && renderer && camera && scene && axesScene && axesCamera) {
      controls.update()

      // 更新状态栏
      calculateFPS()
      updateViewMode()
      updateSystemStatus()

      const width = renderer.domElement.clientWidth
      const height = renderer.domElement.clientHeight

      // 渲染主场景
      renderer.clear()
      renderer.setViewport(0, 0, width, height)
      renderer.setScissor(0, 0, width, height)
      renderer.setScissorTest(false)
      renderer.render(scene, camera)

      // 动态计算 HUD 坐标轴视口大小
      const hudSize = Math.min(width, height) * 0.15
      const margin = 10

      if (width > hudSize + margin && height > hudSize + margin) {
        if (axesGroup) {
          axesGroup.quaternion.copy(camera.quaternion).invert()
          renderer.clearDepth()
          renderer.setViewport(margin, margin, hudSize, hudSize)
          renderer.setScissor(margin, margin, hudSize, hudSize)
          renderer.setScissorTest(true)
          renderer.render(axesScene, axesCamera)
        }
      }

      if (needsRender.value || isResizingLeft || isResizingRight) {
        if (!isResizingLeft && !isResizingRight) {
          needsRender.value = false
        }
      }
    }
  } catch (error) {
    console.error('动画循环错误:', error)
    systemStatus.value = '渲染错误'
    systemStatusClass.value = 'status-error'
  }
};

const isFetchingPoints = ref(false)

// 修改获取监测点的函数，过滤屏蔽区域内的点
// 仅获取监测点，不做任何绘图操作！！
const fetchMonitoringPoints = async (): Promise<void> => {

  if (isFetchingPoints.value) return

  isFetchingPoints.value = true

  try {
    const response = await axios.get('/get_alert_monitoring_points/');

    if (!Array.isArray(response.data)) {
      console.error('返回的数据不是数组:', response.data);
      throw new Error('API 返回的数据不是数组');
    }

    const validLevels = ['ERROR', 'WARNING', 'ATTENTION', 'NORMAL'];

    monitoringPoints.value = response.data.filter((p: MonitoringPoint) => {
      const lvl = p.alert_level?.toUpperCase();
      return validLevels.includes(lvl ?? '');
    });

    console.log(`获取到 ${monitoringPoints.value.length} 条监测点`);

    // 初始化监测点可见性（不改变 Three.js）
    monitoringPoints.value.forEach(p => {
      if (visibility.value[p.point_name] === undefined) {
        visibility.value[p.point_name] = true;
      }
    });

    addMonitoringPoints()
    updateTreeData()

  } catch (error) {
    console.error('获取监测点错误:', error);
  }
  finally {
    isFetchingPoints.value = false
  }
};


const updateTreeData = (): void => {
  //console.log('Updating tree data with monitoring points:', monitoringPoints.value);
  const data: TreeNode[] = [
    {
      id: 'monitoring',
      label: '监测点',
      children: [],
    },
    {
      id: 'model',
      label: '采场模型',
      children: model ? [{ id: 'model_output0', label: model.name, type: 'model' }] : [],
    },
  ];

  const typeMap: Record<string, TreeNode[]> = {};
  monitoringPoints.value.forEach((point: MonitoringPoint, index: number) => {
    if (!typeMap[point.point_type]) {
      typeMap[point.point_type] = [];
    }
    typeMap[point.point_type].push({
      id: `point_${index}`,
      label: point.point_name,
      type: 'point',
      alert_level: point.alert_level,
      x: point.x,
      y: point.y,
      z: point.z,
      point_id: point.point_id,
    });
  });

  data[0].children = Object.keys(typeMap).map((type) => ({
    id: `type_${type}`,
    label: type,
    type: 'category',
    children: typeMap[type],
  }));

  data.forEach((item) => {
    if (visibility.value[item.id] === undefined) {
      visibility.value[item.id] = true;
    }
    if (item.children) {
      item.children.forEach((child) => {
        if (visibility.value[child.id] === undefined) {
          visibility.value[child.id] = true;
        }
        if (child.children) {
          child.children.forEach((subChild) => {
            if (visibility.value[subChild.id] === undefined) {
              visibility.value[subChild.id] = true;
            }
            //console.log('SubChild data:', subChild);
          });
        }
      });
    }
  });

  treeData.value = data;
};

const getAlertClass = (alertLevel: 'ERROR' | 'WARNING' | 'ATTENTION' | null): string => {
  switch (alertLevel) {
    case 'ERROR':
      return 'alert-error';
    case 'WARNING':
      return 'alert-warning';
    case 'ATTENTION':
      return 'alert-attention';
    default:
      return 'alert-normal';
  }
};

const isNodeVisible = (data: TreeNode): boolean => {
  const key = data.id || data.label;
  
  // 统一使用 visibility.value 中的状态，避免直接访问 scene
  if (data.type === 'point') {
    return (visibility.value[key] ?? true) !== false;
  }
  
  if (data.type === 'model') {
    return (visibility.value[key] ?? true) !== false;
  }
  
  if (data.type === 'category') {
    return data.children!.some((child) => {
      return (visibility.value[child.id] ?? true) !== false;
    });
  }
  
  if (!data.children) {
    return false;
  }
  
  return data.children.some((child) => {
    if (child.children) {
      return child.children.some((subChild) => {
        return (visibility.value[subChild.id] ?? true) !== false;
      });
    }
    
    if (child.type === 'point') {
      return (visibility.value[child.id] ?? true) !== false;
    }
    
    return (visibility.value[child.id] ?? true) !== false;
  });
};

const toggleVisibility = (data: TreeNode, node: any, event: MouseEvent): void => {
  event.stopPropagation();
  event.preventDefault();
  console.log('Toggling visibility for:', data.label, 'Type:', data.type);

  const key = data.id || data.label;

  if (data.type === 'point') {
    // 监测点：同时控制小球和文字标注
    const newState = !(visibility.value[key] ?? true);
    visibility.value[key] = newState;
    
    // 获取监测点小球对象（添加空值检查）
    const pointMesh = scene?.getObjectByName(`point_${data.label}`);
    // 获取文字标注对象（添加空值检查）
    const labelSprite = scene?.getObjectByName(`label_${data.label}`);
    
    if (pointMesh) {
      pointMesh.visible = newState;
      console.log(`Point mesh ${data.label} visibility set to:`, pointMesh.visible);
    }
    if (labelSprite) {
      labelSprite.visible = newState;
      console.log(`Label ${data.label} visibility set to:`, labelSprite.visible);
    }
    
  } else if (data.type === 'model') {
    // 模型：控制整个模型
    const newState = !(visibility.value[key] ?? true);
    visibility.value[key] = newState;
    if (model) {
      model.visible = newState;
      console.log(`Model visibility set to:`, model.visible);
    }
    
  } else if (data.type === 'category') {
    // 监测点类别：控制该类别下所有监测点
    const newState = !isNodeVisible(data);
    data.children!.forEach((child) => {
      visibility.value[child.id] = newState;
      
      // 控制该类别下所有监测点的小球和文字标注（添加空值检查）
      const pointMesh = scene?.getObjectByName(`point_${child.label}`);
      const labelSprite = scene?.getObjectByName(`label_${child.label}`);
      
      if (pointMesh) {
        pointMesh.visible = newState;
        console.log(`Point mesh ${child.label} visibility set to:`, newState);
      }
      if (labelSprite) {
        labelSprite.visible = newState;
        console.log(`Label ${child.label} visibility set to:`, newState);
      }
    });
    
  } else {
    // 根节点（监测点组）：控制所有监测点
    const newState = !isNodeVisible(data);
    if (data.label === '监测点') {
      data.children!.forEach((category) => {
        category.children!.forEach((child) => {
          visibility.value[child.id] = newState;
          
          // 控制所有监测点的小球和文字标注（添加空值检查）
          const pointMesh = scene?.getObjectByName(`point_${child.label}`);
          const labelSprite = scene?.getObjectByName(`label_${child.label}`);
          
          if (pointMesh) {
            pointMesh.visible = newState;
            console.log(`Point mesh ${child.label} visibility set to:`, newState);
          }
          if (labelSprite) {
            labelSprite.visible = newState;
            console.log(`Label ${child.label} visibility set to:`, newState);
          }
        });
      });
    } else if (data.label === '采场模型') {
      // 模型组
      const newState = !isNodeVisible(data);
      if (model) {
        model.visible = newState;
        console.log(`Model visibility set to:`, newState);
      }
      data.children!.forEach((child) => {
        visibility.value[child.id] = newState;
      });
    }
  }
  
  // 触发重新渲染
  needsRender.value = true;
  
  // 强制重新渲染树组件
  nextTick(() => {
    if (treeRef.value) {
      // 强制树组件更新
      treeData.value = [...treeData.value];
    }
  });
};

const handleLabelClick = (node: any, event: MouseEvent): void => {
  event.stopPropagation();
  event.preventDefault();
  console.log('Node label clicked:', node.label, 'Data:', node.data);
  handleNodeClick(node.data || node);
  currentNodeKey.value = node.data.id;
};

const handleNodeClick = (data: TreeNode): void => {
  console.log('Handling node click:', data.label, 'Type:', data.type, 'Full data:', data);
  selectedProperties.value = [];

  if (data.type === 'point') {
    selectedProperties.value = [
      { key: 'X 坐标', value: data.x?.toString() || 'N/A' },
      { key: 'Y 坐标', value: data.y?.toString() || 'N/A' },
      { key: 'Z 坐标', value: data.z?.toString() || 'N/A' },
      { key: '告警级别', value: data.alert_level || 'N/A' },
    ];
  } else if (data.type === 'model' && model) {
    const box = new THREE.Box3().setFromObject(model);
    const size = box.getSize(new THREE.Vector3());
    selectedProperties.value = [
      { key: '中心 X', value: modelCenter.value.x.toFixed(2) || 'N/A' },
      { key: '中心 Y', value: modelCenter.value.y.toFixed(2) || 'N/A' },
      { key: '中心 Z', value: modelCenter.value.z.toFixed(2) || 'N/A' },
      { key: '宽度', value: size.x.toFixed(2) || 'N/A' },
      { key: '高度', value: size.y.toFixed(2) || 'N/A' },
      { key: '深度', value: size.z.toFixed(2) || 'N/A' },
    ];
  } else {
    console.log('No properties set for node type:', data.type);
  }
};

// 修改右键菜单显示逻辑
const handleNodeContextMenu = (data: TreeNode, node: any, event: MouseEvent): void => {
  if (event && typeof event.preventDefault === 'function') {
    event.preventDefault();
    event.stopPropagation();
  }

  console.log('Node context menu triggered:', data.label, 'Type:', data.type, 'Event:', event);

  // 保存当前节点信息
  currentNodeKey.value = data.id;

  if (event && event.clientX && event.clientY) {
    contextMenuPos.value = { x: event.clientX, y: event.clientY };

    // 根据选中对象类型显示不同的菜单
    if (selectedObject.value) {
      // 如果有选中的对象（来自点击选择），根据对象类型显示菜单
      showContextMenuForSelectedObject();
    } else if (data.type === 'point') {
      // 如果是树节点的监测点，显示监测点菜单
      showPointContextMenu();
    } else {
      // 其他情况不显示菜单
      contextMenuVisible.value = false;
    }

    console.log('Showing context menu at:', contextMenuPos.value);
  } else {
    console.error('Invalid event object:', event);
  }
};

// 显示监测点的右键菜单
const showPointContextMenu = (): void => {
  contextMenuVisible.value = true;
  console.log('显示监测点右键菜单');
};

// 根据选中的对象类型显示相应的右键菜单
const showContextMenuForSelectedObject = (): void => {
  if (!selectedObject.value) {
    contextMenuVisible.value = false;
    return;
  }

  switch (selectedObject.value.type) {
    case 'point':
      showPointContextMenu();
      break;
    case 'shield':
      showShieldAreaContextMenu();
      break;
    case 'model':
      // 模型可以显示模型相关的菜单，或者不显示
      contextMenuVisible.value = false;
      console.log('模型对象，不显示右键菜单');
      break;
    default:
      contextMenuVisible.value = false;
  }
};

// 显示屏蔽区域的右键菜单 - 直接打开管理对话框
const showShieldAreaContextMenu = (): void => {
  contextMenuVisible.value = false; // 不显示传统菜单
  console.log('打开屏蔽区域管理对话框');

  // 直接打开屏蔽区域管理对话框
  openShieldAreaManagement();
};

// 打开屏蔽区域管理对话框
const openShieldAreaManagement = (): void => {
  console.log('=== 打开屏蔽区域管理 ===');
  console.log('选中的屏蔽区域:', selectedObject.value);
  
  if (!selectedObject.value || selectedObject.value.type !== 'shield') {
    ElMessage.warning('请先选择屏蔽区域');
    return;
  }

  // 获取屏蔽区域ID
  const shieldAreaId = selectedObject.value.id.replace('shield_', '');
  console.log('要管理的屏蔽区域ID:', shieldAreaId);

  // 打开屏蔽区域管理对话框
  if (maskAreaSettingsRef.value) {
    const environment = {
      scene: scene,
      camera: camera,
      renderer: renderer,
      domElement: getCanvasElement(),
      modelCenter: modelCenter.value,
      scaleFactor: scaleFactor,
      // 将选中ID放在环境对象中
      selectedShieldAreaId: shieldAreaId
    };
    
    // 只传递一个参数
    maskAreaSettingsRef.value.open(environment);
    
  } else {
    console.error('maskAreaSettingsRef 未找到');
    ElMessage.error('组件引用未就绪');
  }
};

const nodeExpanded = (data: TreeNode): void => {
  if (!defaultExpandedKeys.value.includes(data.id)) {
    defaultExpandedKeys.value.push(data.id);
  }
  console.log('Node expanded:', data.label, 'Data:', data);
};

const nodeCollapsed = (data: TreeNode): void => {
  const index = defaultExpandedKeys.value.indexOf(data.id);
  if (index > -1) {
    defaultExpandedKeys.value.splice(index, 1);
  }
  console.log('Node collapsed:', data.label, 'Data:', data);
};

// 统一处理右键菜单命令
const handleContextMenuCommand = (command: string): void => {
  contextMenuVisible.value = false;
  console.log('Context menu command:', command);
  
  // 获取当前选中的监测点名称
  const pointName = getCurrentPointName();
  if (!pointName) {
    ElMessage.warning('未找到选中的监测点');
    return;
  }
  
  // 查找监测点数据
  const point = monitoringPoints.value.find((p) => p.point_name === pointName);
  if (!point || !point.point_id) {
    ElMessage.error(`监测点 ${pointName} 数据不完整`);
    return;
  }
  
  const pointId = point.point_id;
  
  switch (command) {
    case 'locate':
      focusOnSelectedObject();
      break;
    case 'viewData':
      console.log('查看数据，点ID:', pointId);
      monitoringDialogRef.value?.open(pointId);
      break;
    case 'viewDisplacement':
      console.log('查看位移曲线，点ID:', pointId);
      displacementChartRef.value?.open(pointId);
      break;
    case 'viewVelocity':
      console.log('查看速率曲线，点ID:', pointId);
      velocityChartRef.value?.open(pointId);
      break;
    case 'viewAcceleration':
      console.log('查看加速度曲线，点ID:', pointId);
      accelerationChartRef.value?.open(pointId);
      break;
    case 'specialAttention':
      console.log('特别关注，点ID:', pointId);
      specialAttention();
      break;
  }
};

const closeContextMenu = (): void => {
  contextMenuVisible.value = false;
  if (highlightedPoint.value) {
    const mesh = scene?.getObjectByName(highlightedPoint.value) as THREE.Mesh | undefined;
    if (mesh) {
      const point = monitoringPoints.value.find((p) => p.point_name === highlightedPoint.value);
      const originalMaterial = getAlertMaterial(point?.alert_level ?? null);
      mesh.material = originalMaterial;
    }
    const label = scene?.getObjectByName(`label_${highlightedPoint.value}`);
    if (label) {
      const point = monitoringPoints.value.find((p) => p.point_name === highlightedPoint.value);
      const originalColor = getAlertColor(point?.alert_level ?? null);
      const newSprite = createLabelSprite(highlightedPoint.value, originalColor);
      newSprite.position.copy(label.position);
      newSprite.visible = label.visible;
      newSprite.name = label.name;
      scene?.remove(label);
      scene?.add(newSprite);
    }
    highlightedPoint.value = null;
  }
  console.log('Context menu closed, contextMenuVisible:', contextMenuVisible.value);
};

const locate = (): void => {
  console.log('定位（兼容旧函数）');
  focusOnSelectedObject();
};

// 查看数据
const viewData = async (): Promise<void> => {
  contextMenuVisible.value = false;
  const pointId = getCurrentPointId();
  if (!pointId) {
    ElMessage.warning('请先选择监测点');
    return;
  }
  monitoringDialogRef.value?.open(pointId);
};

// 查看位移曲线
const viewDisplacement = async (): Promise<void> => {
  contextMenuVisible.value = false;
  const pointId = getCurrentPointId();
  if (!pointId) {
    ElMessage.warning('请先选择监测点');
    return;
  }
  displacementChartRef.value?.open(pointId);
};

// 查看速度曲线
const viewVelocity = async (): Promise<void> => {
  contextMenuVisible.value = false;
  const pointId = getCurrentPointId();
  if (!pointId) {
    ElMessage.warning('请先选择监测点');
    return;
  }
  velocityChartRef.value?.open(pointId);
};

// 查看加速度曲线
const viewAcceleration = async (): Promise<void> => {
  contextMenuVisible.value = false;
  const pointId = getCurrentPointId();
  if (!pointId) {
    ElMessage.warning('请先选择监测点');
    return;
  }
  accelerationChartRef.value?.open(pointId);
};

// 特别关注
const specialAttention = (): void => {
  contextMenuVisible.value = false;
  const pointName = getCurrentPointName();
  if (pointName) {
    console.log('特别关注监测点:', pointName);
    ElMessage.success(`已特别关注监测点: ${pointName}`);
    // 这里可以添加特别关注的业务逻辑
  } else {
    ElMessage.warning('请先选择监测点');
  }
};

const toggleLeftPanel = (): void => {
  showLeftPanel.value = !showLeftPanel.value;
  console.log('Toggled left panel to:', showLeftPanel.value);
  localStorage.setItem('leftPanelState', showLeftPanel.value.toString());
  leftPanelWidth.value = showLeftPanel.value
    ? parseInt(localStorage.getItem('leftPanelWidth') ?? '200')
    : minPanelWidth;
  nextTick(() => updateCanvasSize());
};

const toggleRightPanel = (): void => {
  showRightPanel.value = !showRightPanel.value;
  console.log('Toggled right panel to:', showRightPanel.value);
  localStorage.setItem('rightPanelState', showRightPanel.value.toString());
  rightPanelWidth.value = showRightPanel.value
    ? parseInt(localStorage.getItem('rightPanelWidth') ?? '300')
    : minPanelWidth;
  nextTick(() => updateCanvasSize());
};

const startResizeLeft = (event: MouseEvent): void => {
  if (!showLeftPanel.value) return;
  isResizingLeft = true;
  document.addEventListener('mousemove', resizeLeft);
  document.addEventListener('mouseup', stopResizeLeft);
};

const resizeLeft = (event: MouseEvent): void => {
  if (!isResizingLeft) return;
  let newWidth = event.clientX;
  newWidth = Math.max(minPanelWidth, Math.min(maxPanelWidth, newWidth));
  leftPanelWidth.value = newWidth;
  localStorage.setItem('leftPanelWidth', leftPanelWidth.value.toString());
  updateCanvasSize();
};

const stopResizeLeft = (): void => {
  isResizingLeft = false;
  document.removeEventListener('mousemove', resizeLeft);
  document.removeEventListener('mouseup', stopResizeLeft);
};

const startResizeRight = (event: MouseEvent): void => {
  if (!showRightPanel.value) return;
  isResizingRight = true;
  document.addEventListener('mousemove', resizeRight);
  document.addEventListener('mouseup', stopResizeRight);
};

const resizeRight = (event: MouseEvent): void => {
  if (!isResizingRight) return;
  let newWidth = window.innerWidth - event.clientX;
  newWidth = Math.max(minPanelWidth, Math.min(maxPanelWidth, newWidth));
  rightPanelWidth.value = newWidth;
  localStorage.setItem('rightPanelWidth', rightPanelWidth.value.toString());
  updateCanvasSize();
};

const stopResizeRight = (): void => {
  isResizingRight = false;
  document.removeEventListener('mousemove', resizeRight);
  document.removeEventListener('mouseup', stopResizeRight);
};

// 修改全屏功能
const toggleFullscreen = (): void => {
  if (!document.fullscreenElement) {
    canvas.value?.requestFullscreen().then(() => {
      isFullscreen.value = true;
      updateCanvasSize();
    }).catch((err) => {
      console.error('全屏请求失败:', err);
    });
  } else {
    document.exitFullscreen().then(() => {
      isFullscreen.value = false;
      updateCanvasSize();
    }).catch((err) => {
      console.error('退出全屏失败:', err);
    });
  }
};

const zoomIn = (): void => {
  if (camera) camera.position.z -= 500;
  updateHint('放大视图')
};

const zoomOut = (): void => {
  if (camera) camera.position.z += 500;
  updateHint('缩小视图')
};

const resetView = (): void => {
  if (!model) return;

  const box = new THREE.Box3().setFromObject(model);
  const size = box.getSize(new THREE.Vector3());
  const maxDim = Math.max(size.x, size.y, size.z);
  const fov = camera!.fov * (Math.PI / 180);
  const cameraZ = maxDim / (2 * Math.tan(fov / 2));

  camera!.position.set(modelCenter.value.x, modelCenter.value.y, cameraZ * 1.5 * scaleFactor);
  controls!.target.set(modelCenter.value.x, modelCenter.value.y, modelCenter.value.z);
  controls!.update();
  updateHint('视图已重置')
};

// 添加一个强制布局重排的函数
const forceReflow = (): Promise<void> => {
  return new Promise((resolve) => {
    void document.body.offsetHeight;
    setTimeout(resolve, 50);
  });
};

const updateCanvasSize = (): void => {
  if (!camera || !renderer || !canvas.value) {
    console.warn('无法更新画布尺寸，缺失必要对象');
    return;
  }

  let canvasWidth: number, canvasHeight: number;

  if (isFullscreen.value) {
    canvasWidth = window.innerWidth;
    canvasHeight = window.innerHeight;
  } else {
    const effectiveLeftWidth = showLeftPanel.value ? leftPanelWidth.value : minPanelWidth;
    const effectiveRightWidth = showRightPanel.value ? rightPanelWidth.value : minPanelWidth;
    canvasWidth = Math.max(1, window.innerWidth - effectiveLeftWidth - effectiveRightWidth);

    const headerHeight = 30;
    const statusBarHeight = 28;
    const totalUsedHeight = headerHeight + statusBarHeight;
    canvasHeight = Math.max(1, window.innerHeight - totalUsedHeight);
  }

  camera.aspect = canvasWidth / canvasHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(canvasWidth, canvasHeight);

  const canvasElement = renderer.domElement;
  canvasElement.style.width = `${canvasWidth}px`;
  canvasElement.style.height = `${canvasHeight}px`;

  if (canvas.value) {
    canvas.value.style.width = `${canvasWidth}px`;
    canvas.value.style.height = `${canvasHeight}px`;
    canvas.value.style.margin = '0';
    canvas.value.style.padding = '0';
    canvas.value.style.border = 'none';
  }

  console.log('Canvas 尺寸更新:', canvasWidth, 'x', canvasHeight);
  needsRender.value = true;
};

// 修改初始化逻辑，添加布局检测
const checkLayoutStable = async (): Promise<boolean> => {
  return new Promise((resolve) => {
    let stableCount = 0;
    let lastHeight = 0;

    const check = () => {
      const currentHeight = canvas.value?.clientHeight || 0;

      if (currentHeight > 100 && currentHeight === lastHeight) {
        stableCount++;
        if (stableCount >= 2) {
          console.log('布局稳定，高度:', currentHeight);
          resolve(true);
          return;
        }
      } else {
        stableCount = 0;
      }

      lastHeight = currentHeight;

      if (stableCount < 5) {
        setTimeout(check, 100);
      } else {
        console.log('布局检测超时，使用当前高度:', currentHeight);
        resolve(true);
      }
    };

    check();
  });
};

// 添加等待 Three.js 就绪的函数
const waitForThreeJSReady = async (timeout = 5000) => {
  return new Promise((resolve, reject) => {
    const startTime = Date.now()

    const check = () => {
      if (scene && camera && renderer && getCanvasElement()) {
        resolve(true)
        return
      }

      if (Date.now() - startTime > timeout) {
        reject(new Error('等待 Three.js 就绪超时'))
        return
      }

      setTimeout(check, 100)
    }

    check()
  })
}



//俯视图
const switchToAboveView = (): void => {
  if (!camera || !controls || !model) return;

  const box = new THREE.Box3().setFromObject(model);
  const size = box.getSize(new THREE.Vector3());
  const maxDim = Math.max(size.x, size.y, size.z);
  const distance = maxDim * 0.5 * scaleFactor;

  camera.position.set(
    modelCenter.value.x,
    modelCenter.value.y,
    modelCenter.value.z + distance
  );
  controls.target.set(
    modelCenter.value.x,
    modelCenter.value.y,
    modelCenter.value.z
  );
  camera.up.set(0, 1, 0);
  controls.update();
  if (renderer && scene) renderer.render(scene, camera);
  updateHint('已切换到俯视图')
};

//仰视
const switchToBelowView = (): void => {
  if (!camera || !controls || !model) return;
  const box = new THREE.Box3().setFromObject(model);
  const size = box.getSize(new THREE.Vector3());
  const maxDim = Math.max(size.x, size.y, size.z);
  const distance = maxDim * 0.5 * scaleFactor;

  camera.position.set(modelCenter.value.x, modelCenter.value.y, modelCenter.value.z - distance);
  controls.target.set(modelCenter.value.x, modelCenter.value.y, modelCenter.value.z);

  camera.up.set(0, 1, 0);
  controls.update();
  if (renderer && scene) renderer.render(scene, camera);
  updateHint('已切换到仰视图')
};

//东北等轴测
const switchToEastNorthView = (): void => {
  if (!camera || !controls || !model) return;

  const box = new THREE.Box3().setFromObject(model);
  const size = box.getSize(new THREE.Vector3());
  const maxDim = Math.max(size.x, size.y, size.z);
  const distance = maxDim * 0.5 * scaleFactor;

  const isoDistance = distance / Math.sqrt(3);

  camera.position.set(
    modelCenter.value.x + isoDistance,
    modelCenter.value.y - isoDistance,
    modelCenter.value.z + isoDistance
  );

  controls.target.set(
    modelCenter.value.x,
    modelCenter.value.y,
    modelCenter.value.z
  );

  camera.up.set(0, 0, 1);
  controls.update();
  if (renderer && scene) renderer.render(scene, camera);
  updateHint('已切换到东北等轴测视图')
};

//东南等轴测
const switchToEastSouthView = (): void => {
  if (!camera || !controls || !model) return;

  const box = new THREE.Box3().setFromObject(model);
  const size = box.getSize(new THREE.Vector3());
  const distance = Math.max(size.x, size.y, size.z) * 0.5 * scaleFactor;
  const isoDistance = distance / Math.sqrt(3);

  camera.position.set(
    modelCenter.value.x + isoDistance,
    modelCenter.value.y + isoDistance,
    modelCenter.value.z + isoDistance
  );
  controls.target.set(
    modelCenter.value.x,
    modelCenter.value.y,
    modelCenter.value.z
  );
  camera.up.set(0, 0, 1);
  controls.update();
  if (renderer && scene) renderer.render(scene, camera);
  updateHint('已切换到东南等轴测视图')
};

//西北等轴测
const switchToWestNorthView = (): void => {
  if (!camera || !controls || !model) return;

  const box = new THREE.Box3().setFromObject(model);
  const size = box.getSize(new THREE.Vector3());
  const distance = Math.max(size.x, size.y, size.z) * 0.5 * scaleFactor;
  const isoDistance = distance / Math.sqrt(3);

  camera.position.set(
    modelCenter.value.x - isoDistance,
    modelCenter.value.y - isoDistance,
    modelCenter.value.z + isoDistance
  );
  controls.target.set(
    modelCenter.value.x,
    modelCenter.value.y,
    modelCenter.value.z
  );
  camera.up.set(0, 0, 1);
  controls.update();
  if (renderer && scene) renderer.render(scene, camera);
  updateHint('已切换到西北等轴测视图')
};

//西南等轴测
const switchToWestSouthView = (): void => {
  if (!camera || !controls || !model) return;

  const box = new THREE.Box3().setFromObject(model);
  const size = box.getSize(new THREE.Vector3());
  const distance = Math.max(size.x, size.y, size.z) * 0.5 * scaleFactor;
  const isoDistance = distance / Math.sqrt(3);

  camera.position.set(
    modelCenter.value.x - isoDistance,
    modelCenter.value.y + isoDistance,
    modelCenter.value.z + isoDistance
  );
  controls.target.set(
    modelCenter.value.x,
    modelCenter.value.y,
    modelCenter.value.z
  );
  camera.up.set(0, 0, 1);
  controls.update();
  if (renderer && scene) renderer.render(scene, camera);
  updateHint('已切换到西南等轴测视图')
};

const onFullscreenChange = (): void => {
  isFullscreen.value = !!document.fullscreenElement;
  updateCanvasSize();
};

// 修改 resize 事件处理
const onResize = (): void => {
  updateCanvasSize();
};

// 修改页面跳转控制，添加异步等待
const handleMenuSelect = async (index: string): Promise<void> => {
  activeMenu.value = index;
  console.log('Selected menu item:', index);

  switch (index) {
    // ========== 数据管理中心 ==========
    case '1-1':
      console.log('进入监测数据设置');
      monitoringDataSettingsRef.value?.open();
      break;
    case '1-2':
      console.log('开启/关闭自动导入');
      autoinputdataRef.value?.open();
      break;
    case '1-3-1':
      console.log('进入GNSS数据导入');
      gnssImportRef.value?.open();
      break;
    case '1-3-2':
      console.log('进入全站仪数据导入');
      totalStationImportRef.value?.open();
      break;
    case '1-3-3':
      console.log('进入InSAR数据导入');
      insarImportRef.value?.open();
      break;
    case '1-3-4':
      console.log('进入地下水位数据导入');
      groundwaterImportRef.value?.open();
      break;
    case '1-3-5':
      console.log('进入降雨量数据导入');
      rainfallImportRef.value?.open();
      break;
    case '1-4':
      console.log('进入数据质量评估');
      dataQualityAssessmentRef.value?.open();
      break;
    case '1-5':
      console.log('进入多源数据融合配置');
      dataFusionConfigRef.value?.open();
      break;
    case '1-6':
      console.log('进入数据导出');
      dataExportRef.value?.open();
      break;

    // ========== 数据融合分析 ==========
    case '2-1':
      console.log('进入形变-降雨耦合分析');
      deformationRainfallAnalysisRef.value?.open();
      break;
    case '2-2':
      console.log('进入位移-水位-降雨关联分析');
      displacementWaterRainfallAnalysisRef.value?.open();
      break;
    case '2-3':
      console.log('进入主控因素敏感性分析');
      sensitivityAnalysisRef.value?.open();
      break;
    case '2-4':
      console.log('进入滑坡孕育阶段自动识别');
      landslideIncubationRecognitionRef.value?.open();
      break;

    // ========== 判据与风险指标分析 ==========
    case '3-1':
      console.log('进入累积位移分析');
      displacementAnalysisRef.value?.open();
      break;
    case '3-2':
      console.log('进入位移速率分析');
      velocityAnalysisRef.value?.open();
      break;
    case '3-3':
      console.log('进入加速度分析');
      accelerationAnalysisRef.value?.open();
      break;
    case '3-4':
      console.log('进入F-V判据自动识别图');
      fVRecognitionChartRef.value?.open();
      break;
    case '3-5':
      console.log('进入自动诊断报告生成');
      autoDiagnosisReportRef.value?.open();
      break;

    // ========== AI风险评估与模型管理 ==========
    case '4-1':
      console.log('进入数据集管理');
      datasetManagementRef.value?.open();
      break;
    case '4-2':
      console.log('进入AI模型训练');
      aIModelTrainingRef.value?.open();
      break;
    case '4-3':
      console.log('进入风险预测曲线');
      riskPredictionCurveRef.value?.open();
      break;
    case '4-4':
      console.log('进入模型效果对比');
      modelComparisonRef.value?.open();
      break;
    case '4-5':
      console.log('进入预警规则');
      warningRulesRef.value?.open();
      break;

    // ========== 预警信息管理 ==========
    case '5-1':
      console.log('进入历史预警记录');
      warningRecordsRef.value?.open();
      break;
    case '5-2':
      console.log('进入阈值与智能策略混合控制');
      warningHybridStrategyRef.value?.open();
      break;
    case '5-3':
      console.log('进入预警可信度评分');
      warningCredibilityRef.value?.open();
      break;
    case '5-4':
      console.log('进入预警通知');
      warningNotificationRef.value?.open();
      break;

    // ========== 滑坡信息管理 ==========
    case '6-1':
      console.log('进入历史滑坡信息');
      historyLandslideRef.value?.open();
      break;
    case '6-2':
      console.log('进入添加滑坡信息');
      addLandslideRef.value?.open();
      break;

    // ========== 时空演化可视化 ==========
    case '7-1':
      console.log('进入监测点显示设置');
      pointDisplaySettingsRef.value?.open();
      break;
    case '7-2':
      console.log('=== Three.js 环境状态验证 ===')
      console.log('1. 场景对象:', scene)
      console.log('2. 相机对象:', camera)
      console.log('3. 渲染器对象:', renderer)
      console.log('4. Canvas元素:', getCanvasElement())
      console.log('5. 初始化状态:', threeInitialized.value)
      console.log('6. 场景子对象数量:', scene?.children?.length)
      console.log('7. 相机位置:', camera?.position)
      console.log('8. 渲染器尺寸:', renderer?.domElement?.clientWidth, 'x', renderer?.domElement?.clientHeight)

      // 直接检查传递给子组件的对象
      const environment = {
        scene: scene,
        camera: camera,
        renderer: renderer,
        domElement: getCanvasElement(),
        modelCenter: modelCenter.value,
        scaleFactor: scaleFactor
      }

      console.log('=== 传递给子组件的环境 ===', environment)

      // 强制打开对话框并传递环境
      if (maskAreaSettingsRef.value) {
        maskAreaSettingsRef.value.open(environment)
      } else {
        console.error('maskAreaSettingsRef 未找到')
        ElMessage.error('组件引用未就绪')
      }
      break;
    case '7-3':
      console.log('进入变形/速度/加速度时间轴动态');
      deformationTimelineRef.value?.open();
      break;
    case '7-4':
      console.log('进入降雨/水位时间轴动态');
      rainfallWaterTimelineRef.value?.open();
      break;
    case '7-5':
      console.log('进入滑坡孕育区热力图');
      landslideHeatmapRef.value?.open();
      break;

    // ========== 系统设置 ==========
    case '8-1':
      console.log('进入用户管理');
      userManagementRef.value?.open();
      break;
    case '8-2':
      console.log('进入权限设置');
      permissionSettingsRef.value?.open();
      break;
    case '8-3':
      console.log('进入系统日志');
      systemLogRef.value?.open();
      break;
  }
};

// 在组件挂载时加载屏蔽区域
onMounted(async () => {
  console.log('组件挂载完成');

  // 强制移除 body 的默认边距
  document.body.style.margin = '0';
  document.body.style.padding = '0';
  document.body.style.overflow = 'hidden';

  const init = async () => {
    if (!canvas.value) {
      console.warn('Canvas container 未找到，重试中...');
      setTimeout(init, 100);
      return;
    }

    // 强制设置 canvas 容器样式
    canvas.value.style.margin = '0';
    canvas.value.style.padding = '0';
    canvas.value.style.border = 'none';
    canvas.value.style.overflow = 'hidden';

    try {
      // 等待布局稳定
      await checkLayoutStable();
      await forceReflow();

      // 保存初始化 Promise
      initializationPromise.value = initThree()
      await initializationPromise.value

      console.log('Three.js 初始化成功')

      // 加载屏蔽区域
      await loadShieldAreas();

      updateCanvasSize();
      needsRender.value = true;

      // 添加鼠标移动监听
      if (canvas.value) {
        canvas.value.addEventListener('mousemove', handleMouseMove)
      }

      // 启动帧率计算
      fpsInterval = setInterval(calculateFPS, 1000)

    } catch (error) {
      console.error('初始化失败:', error)
      ElMessage.error('三维场景初始化失败，请刷新页面重试')
    }
  }

  setTimeout(() => {
    init();
  }, 100);

  window.addEventListener('resize', onResize);
  document.addEventListener('fullscreenchange', onFullscreenChange);
});

// 添加一个监听器，在布局可能发生变化时重新计算
watch([showLeftPanel, showRightPanel], async () => {
  await nextTick();
  await forceReflow();
  updateCanvasSize();
});

onUnmounted(() => {
  selectionManager.dispose();
  window.removeEventListener('resize', onResize);
  document.removeEventListener('fullscreenchange', onFullscreenChange);
  if (renderer) renderer.dispose();
  // 移除事件监听
  if (canvas.value) {
    canvas.value.removeEventListener('mousemove', handleMouseMove)
  }

  // 清除帧率计算
  if (fpsInterval) {
    clearInterval(fpsInterval)
  }
});

watch([showLeftPanel, showRightPanel, isFullscreen, leftPanelWidth, rightPanelWidth], () => {
  updateCanvasSize();
});

// ========== 新增状态栏相关数据 ==========

// 当前坐标
const currentCoordinates = reactive({
  x: 0,
  y: 0,
  z: 0
})

// 当前视角模式
const currentViewMode = ref('自由视角')

// 操作提示
const currentHint = ref('使用鼠标左键旋转，滚轮缩放，右键平移')

// 系统状态
const systemStatus = ref('正常')
const systemStatusClass = ref('status-normal')

// 帧率计算
const fps = ref(0)
let frameCount = 0
let lastTime = performance.now()
let fpsInterval: number

// 鼠标移动监听
const handleMouseMove = (event: MouseEvent) => {
  if (!camera || !controls) return

  // 更新坐标显示（这里显示的是相机位置，可以根据需要调整为其他坐标）
  currentCoordinates.x = camera.position.x
  currentCoordinates.y = camera.position.y
  currentCoordinates.z = camera.position.z
}

// 更新视角模式
const updateViewMode = () => {
  if (!camera) return

  const { x, y, z } = camera.position
  const { x: tx, y: ty, z: tz } = controls!.target

  // 简单的视角判断逻辑
  if (Math.abs(z - tz) > Math.abs(x - tx) && Math.abs(z - tz) > Math.abs(y - ty)) {
    if (z > tz) {
      currentViewMode.value = '俯视图'
    } else {
      currentViewMode.value = '仰视图'
    }
  } else if (Math.abs(x - tx) > Math.abs(y - ty)) {
    if (x > tx) {
      currentViewMode.value = '东视图'
    } else {
      currentViewMode.value = '西视图'
    }
  } else {
    if (y > ty) {
      currentViewMode.value = '南视图'
    } else {
      currentViewMode.value = '北视图'
    }
  }
}

// 帧率计算函数
const calculateFPS = () => {
  frameCount++
  const currentTime = performance.now()

  if (currentTime - lastTime >= 1000) {
    fps.value = (frameCount * 1000) / (currentTime - lastTime)
    frameCount = 0
    lastTime = currentTime
  }
}

// 更新系统状态
const updateSystemStatus = () => {
  if (!renderer || !scene) {
    systemStatus.value = '初始化中'
    systemStatusClass.value = 'status-warning'
    return
  }

  // 检查 WebGL 上下文
  const context = renderer.getContext()
  if (!context) {
    systemStatus.value = '渲染错误'
    systemStatusClass.value = 'status-error'
    return
  }

  // 检查模型加载状态
  if (!model) {
    systemStatus.value = '加载模型'
    systemStatusClass.value = 'status-warning'
    return
  }

  // 检查监测点
  if (monitoringPoints.value.length === 0) {
    systemStatus.value = '无监测点'
    systemStatusClass.value = 'status-warning'
    return
  }

  systemStatus.value = '正常'
  systemStatusClass.value = 'status-normal'
}

// 更新操作提示
const updateHint = (hint: string) => {
  currentHint.value = hint
  // 3秒后恢复默认提示
  setTimeout(() => {
    currentHint.value = '使用鼠标左键旋转，滚轮缩放，右键平移'
  }, 3000)
}

// 加载屏蔽区域
const loadShieldAreas = async (): Promise<void> => {
  try {
    console.log('开始加载屏蔽区域...');
    const response = await axios.get('/shieldareas/');

    console.log('屏蔽区域API响应:', response.data);

    if (Array.isArray(response.data)) {
      const activeShieldAreas = response.data.filter(area =>
        area.is_active && area.is_visible
      );

      shieldAreas.value = activeShieldAreas;

      console.log(`加载了 ${shieldAreas.value.length} 个可见的屏蔽区域:`,
        shieldAreas.value.map(area => ({
          id: area.id,
          name: area.name,
          is_active: area.is_active,
          is_visible: area.is_visible,
          coordinates: area.coordinates
        }))
      );

      // 渲染屏蔽区域
      renderShieldAreas();

    } else {
      console.warn('屏蔽区域API返回的数据不是数组:', response.data);
    }
  } catch (error) {
    console.error('加载屏蔽区域失败:', error);
  }
};
// 渲染所有屏蔽区域
const renderShieldAreas = (): void => {
  console.log('开始渲染屏蔽区域，数量:', shieldAreas.value.length);

  // 先清除所有现有的屏蔽区域
  clearAllShieldAreas();

  shieldAreas.value.forEach((area, index) => {
    console.log(`渲染第 ${index + 1} 个屏蔽区域:`, area.name, area.id);
    renderShieldArea(area);
  });

  // 更新渲染
  needsRender.value = true;
  console.log('屏蔽区域渲染完成');
};

// 处理显示屏蔽多边形
const handleShowPolygons = (shieldAreasList: any[]) => {
  console.log('显示屏蔽多边形:', shieldAreasList);

  if (!scene) {
    console.error('场景未初始化，无法显示屏蔽多边形');
    ElMessage.error('三维场景未就绪');
    return;
  }

  if (shieldAreasList.length > 0) {
    // 更新本地数据
    shieldAreas.value = shieldAreasList.filter(area => area.is_active && area.is_visible);

    console.log(`准备显示 ${shieldAreas.value.length} 个屏蔽区域`);

    // 重新渲染屏蔽区域
    renderShieldAreas();

    // 重新加载监测点（过滤屏蔽区域内的点）
    fetchMonitoringPoints();

    ElMessage.success(`已显示 ${shieldAreas.value.length} 个屏蔽区域`);
  } else {
    console.log('没有需要显示的屏蔽区域');
    ElMessage.info('没有需要显示的屏蔽区域');
  }
};

// 清除所有屏蔽区域
const clearAllShieldAreas = () => {
  if (!scene) {
    console.warn('清除屏蔽区域失败: 场景未初始化');
    return;
  }

  const shieldObjects: THREE.Object3D[] = [];
  scene.traverse((child) => {
    if (child.name && child.name.startsWith('shield_area_')) {
      shieldObjects.push(child);
    }
  });

  console.log(`找到 ${shieldObjects.length} 个需要清除的屏蔽区域`);

  shieldObjects.forEach(obj => {
    scene!.remove(obj);
    // 清理几何体和材质
    if (obj instanceof THREE.Mesh) {
      obj.geometry.dispose();
      if (Array.isArray(obj.material)) {
        obj.material.forEach(material => material.dispose());
      } else {
        obj.material.dispose();
      }
    }
  });
};

// 将 [[[points]]] 扁平化为 [points]
function flattenCoordinates(coords: any): any[] {
  if (!Array.isArray(coords)) return [];

  let result: any[] = [];

  coords.forEach((poly: any) => {
    if (!Array.isArray(poly)) return;
    poly.forEach((ring: any) => {
      if (!Array.isArray(ring)) return;
      ring.forEach((pt: any) => result.push(pt));
    });
  });

  return result;
}

// 渲染单个屏蔽区域
const renderShieldArea = (area: any) => {
  if (!scene) {
    console.warn('渲染失败：scene 未初始化');
    return;
  }

  // 兼容两种结构：geom.coordinates 或 coordinates
  const rawCoords =
    area?.geom?.coordinates ||
    area?.coordinates;

  if (!rawCoords) {
    console.warn('渲染失败：没有坐标数据', area);
    return;
  }

  // 扁平化坐标结构 [[[points]]] → [points]
  const coordinates = flattenCoordinates(rawCoords);
  console.log(`解析屏蔽区域 ${area.name} 坐标点:`, coordinates);

  if (coordinates.length < 3) {
    console.warn(`屏蔽区域 ${area.name} 坐标点不足，跳过渲染`);
    return;
  }

  try {
    const shape = new THREE.Shape();

    coordinates.forEach((point: any, index: number) => {
      const x = (point.x - COORDINATE_OFFSET.x) * scaleFactor;
      const y = (point.y - COORDINATE_OFFSET.y) * scaleFactor;

      if (index === 0) {
        shape.moveTo(x, y);
      } else {
        shape.lineTo(x, y);
      }
    });

    shape.closePath();

    const geometry = new THREE.ExtrudeGeometry(shape, {
      depth: 10,
      bevelEnabled: false
    });

    const material = new THREE.MeshBasicMaterial({
      color: 0xff0000,
      opacity: 0.3,
      transparent: true,
      side: THREE.DoubleSide
    });

    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.z = 10;
    mesh.name = `shield_area_${area.id}`;
    mesh.userData = {
      shieldAreaId: area.id,
      isShieldArea: true,
      areaName: area.name
    };

    scene.add(mesh);
    console.log(`屏蔽区域 ${area.name} 已渲染，mesh:`, mesh);

  } catch (error) {
    console.error('渲染屏蔽区域失败:', error);
  }
};

// 添加获取 Canvas 元素的方法
const getCanvasElement = (): HTMLCanvasElement | null => {
  if (!renderer) return null;
  return renderer.domElement;
};
// 监听屏蔽区域变化
watch(() => shieldAreas.value, (newAreas) => {
  console.log('屏蔽区域发生变化，重新过滤监测点');
  fetchMonitoringPoints();
}, { deep: true });

// 监听屏蔽区域对话框关闭
watch(() => shieldDialogVisible.value, (newVal) => {
  if (!newVal) {
    // 对话框关闭时重新加载屏蔽区域和监测点
    loadShieldAreas();
  }
});
</script>

<style>
/* 全局样式 */
body,
html {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
}

.el-table {
  --el-table-header-bg-color: #444;
  --el-table-border-color: #666;
  background-color: transparent;
  color: #fff;
}

.el-table--border {
  border-radius: 4px;
}

.el-table th.el-table__cell {
  background-color: #444;
  color: #fff;
}

.el-table td.el-table__cell {
  background-color: #333;
  color: #fff;
}

.el-table tr:hover td.el-table__cell {
  background-color: #444 !important;
}

.right-sidebar h3 {
  margin: 0 0 15px 0;
  padding-bottom: 10px;
  border-bottom: 1px solid #666;
  color: #fff;
}

/* 修复 Element Plus 组件的默认边距 */
.el-container {
  border: none !important;
}

.el-main {
  padding: 0 !important;
  margin: 0 !important;
}

.el-footer {
  margin: 0 !important;
  border: none !important;
}

/* 修复状态栏内部边距 */
.status-bar .el-footer__inner {
  padding: 0 !important;
  margin: 0 !important;
  height: 100% !important;
  display: flex !important;
  align-items: center !important;
}

/* 修复菜单弹出层样式 */
.custom-popper {
  z-index: 3000 !important;
  background-color: #333;
  border: 1px solid #444;
  border-radius: 4px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
}

.custom-popper .el-menu-item {
  color: #fff;
  background-color: #333;
}

.custom-popper .el-menu-item:hover {
  background-color: #444;
  color: #409eff;
}

/* 调整顶部菜单栏高度相关样式 */
.el-menu--horizontal {
  height: 30px !important;
}

.el-menu--horizontal>.el-menu-item,
.el-menu--horizontal>.el-sub-menu .el-sub-menu__title {
  height: 30px !important;
  line-height: 30px !important;
}

.el-menu--horizontal .el-sub-menu__icon-arrow {
  margin-top: -3px !important;
}

.el-menu--horizontal .el-icon {
  font-size: 14px !important;
}
</style>

<style scoped>
/* 组件 scoped 样式 */
/* 重置所有边距和边框 */
* {
  box-sizing: border-box;
}

.slope-monitoring {
  height: 100vh;
  overflow: hidden;
  background-color: #222;
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
}

/* 三维场景加载提示 */
.loading-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  color: white;
}

.loading-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.loading-icon {
  font-size: 48px;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

/* 主布局容器 */
.main-layout {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  height: calc(100vh - 28px) !important;
}

/* 内容容器 */
.content-container {
  flex: 1;
  min-height: 0;
  display: flex;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

/* 主内容区域 */
.main-content-area {
  flex: 1;
  min-height: 0;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-color: #000;
  height: 100%;
}

/* 画布容器 - 修复间隙 */
.canvas-container {
  width: 100%;
  height: 100%;
  background-color: #000;
  position: relative;
  overflow: hidden;
  margin: 0;
  padding: 0;
  border: none;
}

.canvas-container canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
  margin: 0;
  padding: 0;
}

/* 底部状态栏 - 修复间隙 */
.status-bar {
  height: 28px !important;
  background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%) !important;
  border-top: 1px solid #1a252f !important;
  display: flex !important;
  align-items: center;
  padding: 0 16px !important;
  font-size: 12px;
  color: #ecf0f1;
  box-shadow: 0 -1px 8px rgba(0, 0, 0, 0.3);
  z-index: 1000;
  position: relative;
  flex-shrink: 0;
  margin: 0;
  border-bottom: none !important;
}

.status-content {
  display: flex;
  align-items: center;
  width: 100%;
  height: 100%;
  gap: 24px;
}

.status-section {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 8px;
  height: 100%;
  border-right: 1px solid rgba(255, 255, 255, 0.1);
}

.status-section:last-child {
  border-right: none;
}

.status-label {
  font-weight: 600;
  color: #bdc3c7;
  white-space: nowrap;
}

.status-value {
  color: #ecf0f1;
  font-family: 'Courier New', monospace;
  white-space: nowrap;
  min-width: 60px;
}

/* 状态颜色类 */
.status-normal {
  color: #2ecc71 !important;
}

.status-warning {
  color: #f39c12 !important;
}

.status-error {
  color: #e74c3c !important;
}

/* 提示区域特殊样式 */
.hint-section {
  flex: 1;
  min-width: 200px;
}

.hint-section .status-value {
  color: #3498db;
  font-style: italic;
}

/* 响应式调整 */
@media (max-width: 1200px) {
  .status-content {
    gap: 16px;
  }

  .hint-section {
    min-width: 150px;
  }
}

@media (max-width: 768px) {
  .status-bar {
    padding: 0 8px;
    font-size: 11px;
  }

  .status-content {
    gap: 12px;
  }

  .status-section {
    padding: 0 4px;
    gap: 4px;
  }

  .hint-section {
    display: none;
  }
}

/* 修复 header 样式 - 高度调整为30px */
.header {
  height: 30px !important;
  background-color: #333;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
  flex-shrink: 0;
  margin: 0 !important;
  padding: 0 !important;
  border-bottom: 1px solid #444;
}

.top-menu {
  height: 100%;
  background-color: #333;
  color: #fff;
}

/* 调整菜单项高度为30px */
.top-menu .el-menu-item,
.top-menu .el-sub-menu__title {
  height: 30px !important;
  line-height: 30px !important;
  color: #fff;
  display: flex;
  align-items: center;
  font-size: 12px !important;
}

.top-menu .el-menu-item:hover,
.top-menu .el-sub-menu__title:hover {
  background-color: #409eff !important;
  color: #fff !important;
}

.top-menu .el-menu--horizontal>.el-sub-menu .el-sub-menu__title {
  padding: 0 15px !important;
}

.top-menu .el-menu--horizontal>.el-menu-item.is-active,
.top-menu .el-menu--horizontal>.el-sub-menu.is-active .el-sub-menu__title {
  background-color: #409eff;
  color: #fff;
}

.menu-title {
  font-size: 12px !important;
  color: #fff !important;
}

/* 调整菜单图标大小 */
.top-menu .el-icon {
  font-size: 14px !important;
  margin-right: 4px !important;
}

/* 调整子菜单样式 */
.el-menu--horizontal .el-sub-menu .el-menu {
  min-width: 120px !important;
}

.el-menu--horizontal .el-sub-menu .el-menu-item {
  height: 28px !important;
  line-height: 28px !important;
  font-size: 12px !important;
}

/* 浮动工具栏样式 */
.floating-toolbar {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 100;
  background: rgba(51, 51, 51, 0.9);
  border-radius: 6px;
  padding: 6px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
  transition: all 0.3s ease;
  border: 1px solid rgba(255, 255, 255, 0.1);
  display: flex;
  align-items: center;
}

/* 隐藏状态：只显示切换按钮 */
.floating-toolbar.toolbar-hidden {
  width: auto !important;
  padding: 6px !important;
  opacity: 0.7;
}

.floating-toolbar.toolbar-hidden:hover {
  opacity: 0.9;
}

.toolbar-content {
  display: flex;
  align-items: center;
  gap: 6px;
}

.toolbar-btn {
  background: rgba(68, 68, 68, 0.8) !important;
  border: 1px solid rgba(102, 102, 102, 0.6) !important;
  color: #fff !important;
  margin: 0 1px !important;
  padding: 6px !important;
  min-width: 32px !important;
  height: 32px !important;
}

.toolbar-btn:hover {
  background: rgba(85, 85, 85, 0.9) !important;
  border-color: rgba(119, 119, 119, 0.8) !important;
}

/* 确保切换按钮在隐藏状态下仍然可见且位置正确 */
.toolbar-toggle-btn {
  background: rgba(64, 158, 255, 0.8) !important;
  border: 1px solid rgba(64, 158, 255, 0.6) !important;
  color: #fff !important;
  padding: 6px !important;
  min-width: 32px !important;
  height: 32px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  flex-shrink: 0;
}

.toolbar-toggle-btn:hover {
  background: rgba(64, 158, 255, 0.9) !important;
  border-color: rgba(64, 158, 255, 0.8) !important;
}

/* 调整按钮组样式 */
.el-button-group {
  display: flex;
  align-items: center;
}

/* 确保在全屏模式下工具栏也正确显示 */
:fullscreen .floating-toolbar {
  top: 15px;
  right: 15px;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .floating-toolbar {
    top: 8px;
    right: 8px;
    padding: 4px;
  }

  .toolbar-btn {
    padding: 4px !important;
    min-width: 28px !important;
    height: 28px !important;
    margin: 0 1px !important;
  }
}

/* 侧边栏样式调整 */
.sidebar {
  height: 100%;
  display: flex;
  flex-direction: column;
  position: relative;
  background-color: #333;
  color: #fff;
  z-index: 100;
  margin: 0;
  padding: 0;
  border: none;
}

.right-sidebar {
  background-color: #333;
  color: #fff;
  z-index: 100;
}

.sidebar-content {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
  background-color: inherit;
}

.panel-header {
  height: 30px;
  width: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  background-color: rgba(0, 0, 0, 0.1);
  transition: background-color 0.3s;
}

.panel-header:hover {
  background-color: rgba(0, 0, 0, 0.2);
}

.rotate-180 {
  transform: rotate(180deg);
  transition: transform 0.3s;
}

.el-tree {
  background-color: transparent;
  color: inherit;
}

.el-tree-node__content {
  height: 30px;
  display: flex;
  align-items: center;
  background-color: transparent;
  font-size: 12px;
}

/* 提高优先级，强制覆盖悬停背景 */
.right-sidebar .el-tree-node__content:hover {
  background-color: #444 !important;
  color: #fff !important;
}

/* 确保子元素继承正确的悬停样式 */
.right-sidebar .el-tree-node__content:hover .node-label,
.right-sidebar .el-tree-node__content:hover .visibility-icon {
  color: #fff !important;
}

.tree-node-content {
  display: flex;
  align-items: center;
  flex: 1;
  justify-content: space-between;
}

.node-label {
  cursor: pointer;
  flex: 1;
  color: #fff;
  font-size: 12px;
}

.visibility-icon {
  margin-left: 6px;
  cursor: pointer;
  transition: color 0.3s;
  font-size: 12px;
}

.el-tree-node__content:hover .visibility-icon {
  color: #409eff;
}

.visibility-icon:hover {
  color: #409eff;
}

.visibility-icon.is-hidden {
  color: #909399;
}

.el-tree-node__content:hover .visibility-icon.is-hidden {
  color: #409eff;
}

.empty-properties {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 120px;
  color: #888;
  font-size: 12px;
}

.empty-properties .el-icon {
  font-size: 32px;
  margin-bottom: 8px;
  color: #c0c4cc;
}

/* 调整条样式 */
.resizer {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 4px;
  background-color: #666;
  cursor: col-resize;
  user-select: none;
  z-index: 101;
}

.resizer-left {
  right: -2px;
}

.resizer-right {
  left: -2px;
}

.resizer:hover {
  background-color: #409eff;
}

/* 告警级别颜色，仅应用到监测点名 */
.alert-error {
  color: #f56c6c !important;
  font-weight: bold;
}

.alert-warning {
  color: #e6a23c !important;
  font-weight: bold;
}

.alert-attention {
  color: #fadb14 !important;
  font-weight: bold;
}

.alert-normal {
  color: #67c23a !important;
}

/* 右键菜单样式 */
.context-menu {
  background-color: #fff;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  padding: 4px 0;
  z-index: 2000;
}

.context-menu .el-menu {
  border: none;
}

.context-menu .el-menu-item {
  padding: 0 16px;
  line-height: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  font-size: 12px;
}

.context-menu .el-menu-item:hover {
  background-color: #ecf5ff;
  color: #409eff;
}

/* 移除 Element Plus 容器的默认边距 */
.el-container,
.el-header,
.el-main,
.el-aside,
.el-footer {
  margin: 0 !important;
  padding: 0 !important;
}

/* 确保在全屏模式下布局正确 */
:fullscreen .slope-monitoring {
  height: 100vh;
}

:fullscreen .main-layout {
  height: 100%;
}

:fullscreen .content-container {
  height: 100%;
}

:fullscreen .main-content-area {
  height: 100%;
}

:fullscreen .canvas-container {
  height: 100%;
}

/* 滚动条样式 */
.sidebar-content::-webkit-scrollbar {
  width: 4px;
}

.sidebar-content::-webkit-scrollbar-track {
  background: #2d2d2d;
}

.sidebar-content::-webkit-scrollbar-thumb {
  background: #555;
  border-radius: 2px;
}

.sidebar-content::-webkit-scrollbar-thumb:hover {
  background: #777;
}

/* 树节点展开/收起动画 */
.el-tree-node__expand-icon {
  transition: transform 0.3s;
  font-size: 12px;
}

.el-tree-node__expand-icon.expanded {
  transform: rotate(90deg);
}

/* 工具栏图标悬停效果 */
.toolbar-btn .el-icon {
  transition: transform 0.2s;
  font-size: 14px;
}

.toolbar-btn:hover .el-icon {
  transform: scale(1.1);
}

/* 状态栏动画 */
.status-value {
  transition: color 0.3s;
}

.status-value:hover {
  color: #fff !important;
}

/* 加载状态指示器 */
.loading-indicator {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #fff;
  font-size: 14px;
  z-index: 999;
}

/* 网格按钮激活状态 */
.toolbar-btn.is-active {
  background: rgba(64, 158, 255, 0.9) !important;
  border-color: rgba(64, 158, 255, 0.8) !important;
}

/* 侧边栏过渡动画 */
.sidebar {
  transition: width 0.3s ease;
}

.sidebar-content {
  transition: opacity 0.3s ease;
}

/* 选择状态样式 */
.selection-status {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  padding: 8px;
  background: rgba(64, 158, 255, 0.1);
  border-radius: 4px;
}

.selection-tag {
  flex-shrink: 0;
}

.selection-name {
  font-weight: bold;
  color: #fff;
  font-size: 14px;
}

/* 操作按钮区域 */
.selection-actions {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.selection-actions .el-button {
  flex: 1;
  min-width: 80px;
}

/* 提示文本 */
.hint-text {
  display: block;
  margin-top: 8px;
  font-size: 12px;
  color: #888;
  text-align: center;
}

/* 响应式设计 */
@media (max-width: 1024px) {
  .status-content {
    gap: 16px;
  }

  .status-section {
    padding: 0 6px;
  }

  .hint-section {
    min-width: 180px;
  }
}

@media (max-width: 768px) {
  .content-container {
    flex-direction: column;
  }

  .sidebar {
    width: 100% !important;
    height: 150px;
  }

  .main-content-area {
    order: -1;
  }

  .floating-toolbar {
    top: 8px;
    right: 8px;
  }

  .status-bar {
    font-size: 10px;
  }

  .status-content {
    gap: 8px;
  }
}

/* 高对比度模式支持 */
@media (prefers-contrast: high) {
  .status-bar {
    background: #000 !important;
    border-top-color: #fff !important;
  }

  .sidebar {
    background-color: #000 !important;
    border-right: 1px solid #fff;
  }

  .right-sidebar {
    border-left: 1px solid #fff;
  }
}

/* 减少动画模式 */
@media (prefers-reduced-motion: reduce) {

  .floating-toolbar,
  .sidebar,
  .rotate-180,
  .toolbar-btn .el-icon,
  .status-value,
  .el-tree-node__expand-icon {
    transition: none !important;
  }
}
</style>